فهرست منبع

Explorer: Add source snippets to trace output (#3082)

Adds **Source Snippets** for interpreter and type checker's trace
output.
Note: Source snippets are trace for only declarations and statements.
Prabhat Sachdeva 2 سال پیش
والد
کامیت
3cca175a57

+ 2 - 1
explorer/common/trace_stream.h

@@ -41,7 +41,7 @@ enum class ProgramPhase {
 // disproprotionate amount of time to log, so we try to avoid it.
 class TraceStream {
  public:
-  explicit TraceStream() {}
+  explicit TraceStream() = default;
 
   // Returns true if tracing is currently enabled.
   auto is_enabled() const -> bool {
@@ -126,6 +126,7 @@ class TraceStream {
   auto Pop() const -> llvm::raw_ostream& { return *this << "<[] "; }
   auto Not() const -> llvm::raw_ostream& { return *this << "-!- "; }
   auto Skip() const -> llvm::raw_ostream& { return *this << ">>> "; }
+  auto Source() const -> llvm::raw_ostream& { return *this << "*** "; }
 
  private:
   bool in_prelude_ = false;

+ 10 - 0
explorer/interpreter/interpreter.cpp

@@ -1962,6 +1962,11 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
   auto& act = cast<StatementAction>(todo_.CurrentAction());
   const Statement& stmt = act.statement();
 
+  if (trace_stream_->is_enabled()) {
+    trace_stream_->Source() << "statement at (" << stmt.source_loc() << ")\n";
+    *trace_stream_ << "```\n" << stmt << "\n```\n";
+  }
+
   switch (stmt.kind()) {
     case StatementKind::Match: {
       const auto& match_stmt = cast<Match>(stmt);
@@ -2325,6 +2330,11 @@ auto Interpreter::StepDeclaration() -> ErrorOr<Success> {
   Action& act = todo_.CurrentAction();
   const Declaration& decl = cast<DeclarationAction>(act).declaration();
 
+  if (trace_stream_->is_enabled()) {
+    trace_stream_->Source() << "declaration at (" << decl.source_loc() << ")\n";
+    *trace_stream_ << "```\n" << decl << "```\n";
+  }
+
   switch (decl.kind()) {
     case DeclarationKind::VariableDeclaration: {
       const auto& var_decl = cast<VariableDeclaration>(decl);

+ 17 - 0
explorer/interpreter/type_checker.cpp

@@ -4581,6 +4581,12 @@ static auto GetBuiltinInterfaceForAssignOperator(AssignOperator op) -> Builtin {
 auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s,
                                 const ImplScope& impl_scope)
     -> ErrorOr<Success> {
+  if (trace_stream_->is_enabled()) {
+    trace_stream_->Source()
+        << "type checking stmt at (" << s->source_loc() << ")\n";
+    *trace_stream_ << "```\n" << *s << "\n```\n";
+  }
+
   if (trace_stream_->is_enabled()) {
     trace_stream_->Start() << "checking " << s->kind() << " `" << PrintAsID(*s)
                            << "` (" << s->source_loc() << ")\n";
@@ -6177,6 +6183,12 @@ auto TypeChecker::TypeCheckDeclaration(
     Nonnull<Declaration*> d, const ImplScope& impl_scope,
     std::optional<Nonnull<const Declaration*>> enclosing_decl)
     -> ErrorOr<Success> {
+  if (trace_stream_->is_enabled()) {
+    trace_stream_->Source()
+        << "type checking declaration at (" << d->source_loc() << ")\n";
+    *trace_stream_ << "```\n" << *d << "\n```\n";
+  }
+
   if (trace_stream_->is_enabled()) {
     trace_stream_->Start() << "checking " << d->kind() << " `" << PrintAsID(*d)
                            << "` (" << d->source_loc() << ")\n";
@@ -6269,6 +6281,11 @@ auto TypeChecker::TypeCheckDeclaration(
 auto TypeChecker::DeclareDeclaration(Nonnull<Declaration*> d,
                                      const ScopeInfo& scope_info)
     -> ErrorOr<Success> {
+  if (trace_stream_->is_enabled()) {
+    trace_stream_->Source() << "declaration at (" << d->source_loc() << ")\n";
+    *trace_stream_ << "```\n" << *d << "\n```\n";
+  }
+
   switch (d->kind()) {
     case DeclarationKind::NamespaceDeclaration: {
       auto& namespace_decl = cast<NamespaceDeclaration>(*d);

+ 72 - 0
explorer/testdata/trace/context_main.carbon

@@ -44,8 +44,20 @@ fn Main() -> i32 {
 // CHECK:STDOUT: ********** resolving control flow **********
 // CHECK:STDOUT: ==> flow-resolved return statement `return 0;` in `fn Main` (context_main.carbon:10)
 // CHECK:STDOUT: ********** type checking **********
+// CHECK:STDOUT: *** declaration at (context_main.carbon:7)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: interface TestInterface {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> declaring `interface TestInterface` (context_main.carbon:7)
 // CHECK:STDOUT: <<- finished declaring `interface TestInterface` (context_main.carbon:7)
+// CHECK:STDOUT: *** type checking declaration at (context_main.carbon:7)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: interface TestInterface {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> checking InterfaceDeclaration `interface TestInterface` (context_main.carbon:7)
 // CHECK:STDOUT: ->> checking `interface TestInterface` (context_main.carbon:7)
 // CHECK:STDOUT: ==> impl declarations for `interface TestInterface` (context_main.carbon:7)
@@ -98,6 +110,16 @@ fn Main() -> i32 {
 // CHECK:STDOUT:     `T` as `interface LeftShiftAssignWith(U = U)` [0; 1, 1, 0],
 // CHECK:STDOUT:     `T` as `interface RightShiftAssignWith(U = U)` [0; 1, 1, 0]]
 // CHECK:STDOUT: <<- finished checking `interface TestInterface` (context_main.carbon:7)
+// CHECK:STDOUT: *** declaration at (context_main.carbon:11)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: fn Main ()-> i32 {
+// CHECK:STDOUT: {
+// CHECK:STDOUT: return 0;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> declaring function `Main` (context_main.carbon:11)
 // CHECK:STDOUT: ->> checking TuplePattern `()` (context_main.carbon:9)
 // CHECK:STDOUT: ->> checking IntTypeLiteral `i32` (context_main.carbon:9)
@@ -109,6 +131,16 @@ fn Main() -> i32 {
 // CHECK:STDOUT: ->> step ValueExpressionAction pos: 1 `i32` results: [`i32`]  (context_main.carbon:9) --->
 // CHECK:STDOUT: <[] stack-pop:  ValueExpressionAction pos: 1 `i32` results: [`i32`]  (context_main.carbon:9)
 // CHECK:STDOUT: ->> finished declaring function `Main` of type `fn () -> i32` (context_main.carbon:11)
+// CHECK:STDOUT: *** type checking declaration at (context_main.carbon:11)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: fn Main ()-> i32 {
+// CHECK:STDOUT: {
+// CHECK:STDOUT: return 0;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> checking FunctionDeclaration `fn Main` (context_main.carbon:11)
 // CHECK:STDOUT: ->> checking function `Main` (context_main.carbon:11)
 // CHECK:STDOUT: ==> impl declarations for `fn Main` (context_main.carbon:11)
@@ -160,7 +192,18 @@ fn Main() -> i32 {
 // CHECK:STDOUT:     `T` as `interface BitXorAssignWith(U = U)` [0; 1, 1, 0],
 // CHECK:STDOUT:     `T` as `interface LeftShiftAssignWith(U = U)` [0; 1, 1, 0],
 // CHECK:STDOUT:     `T` as `interface RightShiftAssignWith(U = U)` [0; 1, 1, 0]]
+// CHECK:STDOUT: *** type checking stmt at (context_main.carbon:11)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: {
+// CHECK:STDOUT: return 0;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> checking Block `{return 0;}` (context_main.carbon:11)
+// CHECK:STDOUT: *** type checking stmt at (context_main.carbon:10)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: return 0;
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> checking ReturnExpression `return 0;` (context_main.carbon:10)
 // CHECK:STDOUT: ->> checking IntLiteral `0` (context_main.carbon:10)
 // CHECK:STDOUT: ->> finished checking function `Main` (context_main.carbon:11)
@@ -188,9 +231,23 @@ fn Main() -> i32 {
 // CHECK:STDOUT: ********** initializing globals **********
 // CHECK:STDOUT: >[] stack-push: DeclarationAction pos: 0 `interface TestInterface` (context_main.carbon:7)
 // CHECK:STDOUT: ->> step DeclarationAction pos: 0 `interface TestInterface` (context_main.carbon:7) --->
+// CHECK:STDOUT: *** declaration at (context_main.carbon:7)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: interface TestInterface {
+// CHECK:STDOUT: }
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: <[] stack-pop:  DeclarationAction pos: 0 `interface TestInterface` (context_main.carbon:7)
 // CHECK:STDOUT: >[] stack-push: DeclarationAction pos: 0 `fn Main` (context_main.carbon:11)
 // CHECK:STDOUT: ->> step DeclarationAction pos: 0 `fn Main` (context_main.carbon:11) --->
+// CHECK:STDOUT: *** declaration at (context_main.carbon:11)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: fn Main ()-> i32 {
+// CHECK:STDOUT: {
+// CHECK:STDOUT: return 0;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: }
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: <[] stack-pop:  DeclarationAction pos: 0 `fn Main` (context_main.carbon:11)
 // CHECK:STDOUT: ********** calling main function **********
 // CHECK:STDOUT: >[] stack-push: ValueExpressionAction pos: 0 `Main()` (<Main()>:0)
@@ -211,8 +268,19 @@ fn Main() -> i32 {
 // CHECK:STDOUT: >[] stack-push: ScopeAction pos: 0  scope: [] (None)
 // CHECK:STDOUT: >[] stack-push: StatementAction pos: 0 `{return 0;}` (context_main.carbon:11)
 // CHECK:STDOUT: ->> step StatementAction pos: 0 `{return 0;}` (context_main.carbon:11) --->
+// CHECK:STDOUT: *** statement at (context_main.carbon:11)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: {
+// CHECK:STDOUT: return 0;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: >[] stack-push: StatementAction pos: 0 `return 0;` (context_main.carbon:10)
 // CHECK:STDOUT: ->> step StatementAction pos: 0 `return 0;` (context_main.carbon:10) --->
+// CHECK:STDOUT: *** statement at (context_main.carbon:10)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: return 0;
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: >[] stack-push: ValueExpressionAction pos: 0 `0` (context_main.carbon:10)
 // CHECK:STDOUT: ->> step ValueExpressionAction pos: 0 `0` (context_main.carbon:10) --->
 // CHECK:STDOUT: >[] stack-push: ExpressionAction pos: 0 `0` (context_main.carbon:10)
@@ -221,6 +289,10 @@ fn Main() -> i32 {
 // CHECK:STDOUT: ->> step ValueExpressionAction pos: 1 `0` results: [`0`]  (context_main.carbon:10) --->
 // CHECK:STDOUT: <[] stack-pop:  ValueExpressionAction pos: 1 `0` results: [`0`]  (context_main.carbon:10)
 // CHECK:STDOUT: ->> step StatementAction pos: 1 `return 0;` results: [`0`]  (context_main.carbon:10) --->
+// CHECK:STDOUT: *** statement at (context_main.carbon:10)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: return 0;
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: <[] stack-pop:  StatementAction pos: 1 `return 0;` results: [`0`]  (context_main.carbon:10)
 // CHECK:STDOUT: <[] stack-pop:  StatementAction pos: 1 `{return 0;}` scope: [] (context_main.carbon:11)
 // CHECK:STDOUT: <[] stack-pop:  ScopeAction pos: 0  scope: [] (None)

+ 163 - 0
explorer/testdata/trace/phase_all.carbon

@@ -82,8 +82,20 @@ fn Main() -> i32 {
 // CHECK:STDOUT: ==> flow-resolved return statement `return (n + 1);` in `fn N.Foo` (phase_all.carbon:12)
 // CHECK:STDOUT: ==> flow-resolved return statement `return x;` in `fn Main` (phase_all.carbon:17)
 // CHECK:STDOUT: ********** type checking **********
+// CHECK:STDOUT: *** declaration at (phase_all.carbon:7)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: interface TestInterface {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> declaring `interface TestInterface` (phase_all.carbon:7)
 // CHECK:STDOUT: <<- finished declaring `interface TestInterface` (phase_all.carbon:7)
+// CHECK:STDOUT: *** type checking declaration at (phase_all.carbon:7)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: interface TestInterface {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> checking InterfaceDeclaration `interface TestInterface` (phase_all.carbon:7)
 // CHECK:STDOUT: ->> checking `interface TestInterface` (phase_all.carbon:7)
 // CHECK:STDOUT: ==> impl declarations for `interface TestInterface` (phase_all.carbon:7)
@@ -136,7 +148,25 @@ fn Main() -> i32 {
 // CHECK:STDOUT:     `T` as `interface LeftShiftAssignWith(U = U)` [0; 1, 1, 0],
 // CHECK:STDOUT:     `T` as `interface RightShiftAssignWith(U = U)` [0; 1, 1, 0]]
 // CHECK:STDOUT: <<- finished checking `interface TestInterface` (phase_all.carbon:7)
+// CHECK:STDOUT: *** declaration at (phase_all.carbon:9)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: namespace N;
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: *** type checking declaration at (phase_all.carbon:9)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: namespace N;
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> checking NamespaceDeclaration `namespace N` (phase_all.carbon:9)
+// CHECK:STDOUT: *** declaration at (phase_all.carbon:13)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: fn Foo (n: i32)-> i32 {
+// CHECK:STDOUT: {
+// CHECK:STDOUT: return (n + 1);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> declaring function `Foo` (phase_all.carbon:13)
 // CHECK:STDOUT: ->> checking TuplePattern `(n: i32)` (phase_all.carbon:11)
 // CHECK:STDOUT: ->> checking BindingPattern `n: i32` (phase_all.carbon:11)
@@ -159,6 +189,16 @@ fn Main() -> i32 {
 // CHECK:STDOUT: ->> step ValueExpressionAction pos: 1 `i32` results: [`i32`]  (phase_all.carbon:11) --->
 // CHECK:STDOUT: <[] stack-pop:  ValueExpressionAction pos: 1 `i32` results: [`i32`]  (phase_all.carbon:11)
 // CHECK:STDOUT: ->> finished declaring function `Foo` of type `fn (i32,) -> i32` (phase_all.carbon:13)
+// CHECK:STDOUT: *** type checking declaration at (phase_all.carbon:13)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: fn Foo (n: i32)-> i32 {
+// CHECK:STDOUT: {
+// CHECK:STDOUT: return (n + 1);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> checking FunctionDeclaration `fn N.Foo` (phase_all.carbon:13)
 // CHECK:STDOUT: ->> checking function `Foo` (phase_all.carbon:13)
 // CHECK:STDOUT: ==> impl declarations for `fn N.Foo` (phase_all.carbon:13)
@@ -210,12 +250,34 @@ fn Main() -> i32 {
 // CHECK:STDOUT:     `T` as `interface BitXorAssignWith(U = U)` [0; 1, 1, 0],
 // CHECK:STDOUT:     `T` as `interface LeftShiftAssignWith(U = U)` [0; 1, 1, 0],
 // CHECK:STDOUT:     `T` as `interface RightShiftAssignWith(U = U)` [0; 1, 1, 0]]
+// CHECK:STDOUT: *** type checking stmt at (phase_all.carbon:13)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: {
+// CHECK:STDOUT: return (n + 1);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> checking Block `{return (n + 1);}` (phase_all.carbon:13)
+// CHECK:STDOUT: *** type checking stmt at (phase_all.carbon:12)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: return (n + 1);
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> checking ReturnExpression `return (n + 1);` (phase_all.carbon:12)
 // CHECK:STDOUT: ->> checking OperatorExpression `(n + 1)` (phase_all.carbon:12)
 // CHECK:STDOUT: ->> checking IdentifierExpression `n` (phase_all.carbon:12)
 // CHECK:STDOUT: ->> checking IntLiteral `1` (phase_all.carbon:12)
 // CHECK:STDOUT: ->> finished checking function `Foo` (phase_all.carbon:13)
+// CHECK:STDOUT: *** declaration at (phase_all.carbon:18)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: fn Main ()-> i32 {
+// CHECK:STDOUT: {
+// CHECK:STDOUT: var x: i32 = N.Foo(0);
+// CHECK:STDOUT: return x;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> declaring function `Main` (phase_all.carbon:18)
 // CHECK:STDOUT: ->> checking TuplePattern `()` (phase_all.carbon:15)
 // CHECK:STDOUT: ->> checking IntTypeLiteral `i32` (phase_all.carbon:15)
@@ -227,6 +289,17 @@ fn Main() -> i32 {
 // CHECK:STDOUT: ->> step ValueExpressionAction pos: 1 `i32` results: [`i32`]  (phase_all.carbon:15) --->
 // CHECK:STDOUT: <[] stack-pop:  ValueExpressionAction pos: 1 `i32` results: [`i32`]  (phase_all.carbon:15)
 // CHECK:STDOUT: ->> finished declaring function `Main` of type `fn () -> i32` (phase_all.carbon:18)
+// CHECK:STDOUT: *** type checking declaration at (phase_all.carbon:18)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: fn Main ()-> i32 {
+// CHECK:STDOUT: {
+// CHECK:STDOUT: var x: i32 = N.Foo(0);
+// CHECK:STDOUT: return x;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> checking FunctionDeclaration `fn Main` (phase_all.carbon:18)
 // CHECK:STDOUT: ->> checking function `Main` (phase_all.carbon:18)
 // CHECK:STDOUT: ==> impl declarations for `fn Main` (phase_all.carbon:18)
@@ -278,7 +351,19 @@ fn Main() -> i32 {
 // CHECK:STDOUT:     `T` as `interface BitXorAssignWith(U = U)` [0; 1, 1, 0],
 // CHECK:STDOUT:     `T` as `interface LeftShiftAssignWith(U = U)` [0; 1, 1, 0],
 // CHECK:STDOUT:     `T` as `interface RightShiftAssignWith(U = U)` [0; 1, 1, 0]]
+// CHECK:STDOUT: *** type checking stmt at (phase_all.carbon:18)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: {
+// CHECK:STDOUT: var x: i32 = N.Foo(0);
+// CHECK:STDOUT: return x;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> checking Block `{var x: i32 = N.Foo(0);return x;}` (phase_all.carbon:18)
+// CHECK:STDOUT: *** type checking stmt at (phase_all.carbon:16)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: var x: i32 = N.Foo(0);
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> checking VariableDefinition `var x: i32 = N.Foo(0);` (phase_all.carbon:16)
 // CHECK:STDOUT: ->> checking CallExpression `N.Foo(0)` (phase_all.carbon:16)
 // CHECK:STDOUT: ->> checking SimpleMemberAccessExpression `N.Foo` (phase_all.carbon:16)
@@ -299,6 +384,10 @@ fn Main() -> i32 {
 // CHECK:STDOUT: <[] stack-pop:  ExpressionAction pos: 0 `i32` (phase_all.carbon:16)
 // CHECK:STDOUT: ->> step ValueExpressionAction pos: 1 `i32` results: [`i32`]  (phase_all.carbon:16) --->
 // CHECK:STDOUT: <[] stack-pop:  ValueExpressionAction pos: 1 `i32` results: [`i32`]  (phase_all.carbon:16)
+// CHECK:STDOUT: *** type checking stmt at (phase_all.carbon:17)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: return x;
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> checking ReturnExpression `return x;` (phase_all.carbon:17)
 // CHECK:STDOUT: ->> checking IdentifierExpression `x` (phase_all.carbon:17)
 // CHECK:STDOUT: ->> finished checking function `Main` (phase_all.carbon:18)
@@ -341,15 +430,42 @@ fn Main() -> i32 {
 // CHECK:STDOUT: ********** initializing globals **********
 // CHECK:STDOUT: >[] stack-push: DeclarationAction pos: 0 `interface TestInterface` (phase_all.carbon:7)
 // CHECK:STDOUT: ->> step DeclarationAction pos: 0 `interface TestInterface` (phase_all.carbon:7) --->
+// CHECK:STDOUT: *** declaration at (phase_all.carbon:7)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: interface TestInterface {
+// CHECK:STDOUT: }
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: <[] stack-pop:  DeclarationAction pos: 0 `interface TestInterface` (phase_all.carbon:7)
 // CHECK:STDOUT: >[] stack-push: DeclarationAction pos: 0 `namespace N` (phase_all.carbon:9)
 // CHECK:STDOUT: ->> step DeclarationAction pos: 0 `namespace N` (phase_all.carbon:9) --->
+// CHECK:STDOUT: *** declaration at (phase_all.carbon:9)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: namespace N;```
 // CHECK:STDOUT: <[] stack-pop:  DeclarationAction pos: 0 `namespace N` (phase_all.carbon:9)
 // CHECK:STDOUT: >[] stack-push: DeclarationAction pos: 0 `fn N.Foo` (phase_all.carbon:13)
 // CHECK:STDOUT: ->> step DeclarationAction pos: 0 `fn N.Foo` (phase_all.carbon:13) --->
+// CHECK:STDOUT: *** declaration at (phase_all.carbon:13)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: fn Foo (n: i32)-> i32 {
+// CHECK:STDOUT: {
+// CHECK:STDOUT: return (n + 1);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: }
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: <[] stack-pop:  DeclarationAction pos: 0 `fn N.Foo` (phase_all.carbon:13)
 // CHECK:STDOUT: >[] stack-push: DeclarationAction pos: 0 `fn Main` (phase_all.carbon:18)
 // CHECK:STDOUT: ->> step DeclarationAction pos: 0 `fn Main` (phase_all.carbon:18) --->
+// CHECK:STDOUT: *** declaration at (phase_all.carbon:18)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: fn Main ()-> i32 {
+// CHECK:STDOUT: {
+// CHECK:STDOUT: var x: i32 = N.Foo(0);
+// CHECK:STDOUT: return x;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: }
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: <[] stack-pop:  DeclarationAction pos: 0 `fn Main` (phase_all.carbon:18)
 // CHECK:STDOUT: ********** calling main function **********
 // CHECK:STDOUT: >[] stack-push: ValueExpressionAction pos: 0 `Main()` (<Main()>:0)
@@ -370,8 +486,20 @@ fn Main() -> i32 {
 // CHECK:STDOUT: >[] stack-push: ScopeAction pos: 0  scope: [] (None)
 // CHECK:STDOUT: >[] stack-push: StatementAction pos: 0 `{var x: i32 = N.Foo(0);return x;}` (phase_all.carbon:18)
 // CHECK:STDOUT: ->> step StatementAction pos: 0 `{var x: i32 = N.Foo(0);return x;}` (phase_all.carbon:18) --->
+// CHECK:STDOUT: *** statement at (phase_all.carbon:18)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: {
+// CHECK:STDOUT: var x: i32 = N.Foo(0);
+// CHECK:STDOUT: return x;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: >[] stack-push: StatementAction pos: 0 `var x: i32 = N.Foo(0);` (phase_all.carbon:16)
 // CHECK:STDOUT: ->> step StatementAction pos: 0 `var x: i32 = N.Foo(0);` (phase_all.carbon:16) --->
+// CHECK:STDOUT: *** statement at (phase_all.carbon:16)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: var x: i32 = N.Foo(0);
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ++# memory-alloc: #1 `Uninit<i32>` uninitialized
 // CHECK:STDOUT: >[] stack-push: ExpressionAction pos: 0 `N.Foo(0)` (phase_all.carbon:16)
 // CHECK:STDOUT: ->> step ExpressionAction pos: 0 `N.Foo(0)` (phase_all.carbon:16) --->
@@ -398,8 +526,19 @@ fn Main() -> i32 {
 // CHECK:STDOUT: >[] stack-push: ScopeAction pos: 0  scope: [`n: i32`: `0`] (None)
 // CHECK:STDOUT: >[] stack-push: StatementAction pos: 0 `{return (n + 1);}` (phase_all.carbon:13)
 // CHECK:STDOUT: ->> step StatementAction pos: 0 `{return (n + 1);}` (phase_all.carbon:13) --->
+// CHECK:STDOUT: *** statement at (phase_all.carbon:13)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: {
+// CHECK:STDOUT: return (n + 1);
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: >[] stack-push: StatementAction pos: 0 `return (n + 1);` (phase_all.carbon:12)
 // CHECK:STDOUT: ->> step StatementAction pos: 0 `return (n + 1);` (phase_all.carbon:12) --->
+// CHECK:STDOUT: *** statement at (phase_all.carbon:12)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: return (n + 1);
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: >[] stack-push: ValueExpressionAction pos: 0 `(n + 1)` (phase_all.carbon:12)
 // CHECK:STDOUT: ->> step ValueExpressionAction pos: 0 `(n + 1)` (phase_all.carbon:12) --->
 // CHECK:STDOUT: >[] stack-push: ExpressionAction pos: 0 `(n + 1)` (phase_all.carbon:12)
@@ -424,6 +563,10 @@ fn Main() -> i32 {
 // CHECK:STDOUT: ->> step ValueExpressionAction pos: 1 `(n + 1)` results: [`1`]  (phase_all.carbon:12) --->
 // CHECK:STDOUT: <[] stack-pop:  ValueExpressionAction pos: 1 `(n + 1)` results: [`1`]  (phase_all.carbon:12)
 // CHECK:STDOUT: ->> step StatementAction pos: 1 `return (n + 1);` results: [`1`]  (phase_all.carbon:12) --->
+// CHECK:STDOUT: *** statement at (phase_all.carbon:12)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: return (n + 1);
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: --> memory-write: #1 `1`
 // CHECK:STDOUT: <[] stack-pop:  StatementAction pos: 1 `return (n + 1);` results: [`1`]  (phase_all.carbon:12)
 // CHECK:STDOUT: <[] stack-pop:  StatementAction pos: 1 `{return (n + 1);}` scope: [] (phase_all.carbon:13)
@@ -440,13 +583,29 @@ fn Main() -> i32 {
 // CHECK:STDOUT: ->> step CleanUpAction pos: 0  scope: [] (stack cleanup:1) --->
 // CHECK:STDOUT: <[] stack-pop:  CleanUpAction pos: 0  scope: [] (stack cleanup:1)
 // CHECK:STDOUT: ->> step StatementAction pos: 1 `var x: i32 = N.Foo(0);` results: [`1`]  (phase_all.carbon:16) --->
+// CHECK:STDOUT: *** statement at (phase_all.carbon:16)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: var x: i32 = N.Foo(0);
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: <-- memory-read: #1 `1`
 // CHECK:STDOUT: match pattern Placeholder<x>
 // CHECK:STDOUT: from initializing expression with value 1
 // CHECK:STDOUT: <[] stack-pop:  StatementAction pos: 1 `var x: i32 = N.Foo(0);` results: [`1`]  (phase_all.carbon:16)
 // CHECK:STDOUT: ->> step StatementAction pos: 1 `{var x: i32 = N.Foo(0);return x;}` scope: [`x: i32`: `lval<Allocation(1)>`] (phase_all.carbon:18) --->
+// CHECK:STDOUT: *** statement at (phase_all.carbon:18)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: {
+// CHECK:STDOUT: var x: i32 = N.Foo(0);
+// CHECK:STDOUT: return x;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: >[] stack-push: StatementAction pos: 0 `return x;` (phase_all.carbon:17)
 // CHECK:STDOUT: ->> step StatementAction pos: 0 `return x;` (phase_all.carbon:17) --->
+// CHECK:STDOUT: *** statement at (phase_all.carbon:17)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: return x;
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: >[] stack-push: ValueExpressionAction pos: 0 `x` (phase_all.carbon:17)
 // CHECK:STDOUT: ->> step ValueExpressionAction pos: 0 `x` (phase_all.carbon:17) --->
 // CHECK:STDOUT: >[] stack-push: ExpressionAction pos: 0 `x` (phase_all.carbon:17)
@@ -456,6 +615,10 @@ fn Main() -> i32 {
 // CHECK:STDOUT: ->> step ValueExpressionAction pos: 1 `x` results: [`ref_expr<Allocation(1)>`]  (phase_all.carbon:17) --->
 // CHECK:STDOUT: <[] stack-pop:  ValueExpressionAction pos: 1 `x` results: [`ref_expr<Allocation(1)>`]  (phase_all.carbon:17)
 // CHECK:STDOUT: ->> step StatementAction pos: 1 `return x;` results: [`1`]  (phase_all.carbon:17) --->
+// CHECK:STDOUT: *** statement at (phase_all.carbon:17)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: return x;
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: <[] stack-pop:  StatementAction pos: 1 `return x;` results: [`1`]  (phase_all.carbon:17)
 // CHECK:STDOUT: <[] stack-pop:  StatementAction pos: 2 `{var x: i32 = N.Foo(0);return x;}` scope: [`x: i32`: `lval<Allocation(1)>`] (phase_all.carbon:18)
 // CHECK:STDOUT: <[] stack-pop:  ScopeAction pos: 0  scope: [] (None)

+ 29 - 0
explorer/testdata/trace/phase_execution.carbon

@@ -19,9 +19,23 @@ fn Main() -> i32 {
 // CHECK:STDOUT: ********** initializing globals **********
 // CHECK:STDOUT: >[] stack-push: DeclarationAction pos: 0 `interface TestInterface` (phase_execution.carbon:7)
 // CHECK:STDOUT: ->> step DeclarationAction pos: 0 `interface TestInterface` (phase_execution.carbon:7) --->
+// CHECK:STDOUT: *** declaration at (phase_execution.carbon:7)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: interface TestInterface {
+// CHECK:STDOUT: }
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: <[] stack-pop:  DeclarationAction pos: 0 `interface TestInterface` (phase_execution.carbon:7)
 // CHECK:STDOUT: >[] stack-push: DeclarationAction pos: 0 `fn Main` (phase_execution.carbon:11)
 // CHECK:STDOUT: ->> step DeclarationAction pos: 0 `fn Main` (phase_execution.carbon:11) --->
+// CHECK:STDOUT: *** declaration at (phase_execution.carbon:11)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: fn Main ()-> i32 {
+// CHECK:STDOUT: {
+// CHECK:STDOUT: return 0;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: }
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: <[] stack-pop:  DeclarationAction pos: 0 `fn Main` (phase_execution.carbon:11)
 // CHECK:STDOUT: ********** calling main function **********
 // CHECK:STDOUT: >[] stack-push: ValueExpressionAction pos: 0 `Main()` (<Main()>:0)
@@ -42,8 +56,19 @@ fn Main() -> i32 {
 // CHECK:STDOUT: >[] stack-push: ScopeAction pos: 0  scope: [] (None)
 // CHECK:STDOUT: >[] stack-push: StatementAction pos: 0 `{return 0;}` (phase_execution.carbon:11)
 // CHECK:STDOUT: ->> step StatementAction pos: 0 `{return 0;}` (phase_execution.carbon:11) --->
+// CHECK:STDOUT: *** statement at (phase_execution.carbon:11)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: {
+// CHECK:STDOUT: return 0;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: >[] stack-push: StatementAction pos: 0 `return 0;` (phase_execution.carbon:10)
 // CHECK:STDOUT: ->> step StatementAction pos: 0 `return 0;` (phase_execution.carbon:10) --->
+// CHECK:STDOUT: *** statement at (phase_execution.carbon:10)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: return 0;
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: >[] stack-push: ValueExpressionAction pos: 0 `0` (phase_execution.carbon:10)
 // CHECK:STDOUT: ->> step ValueExpressionAction pos: 0 `0` (phase_execution.carbon:10) --->
 // CHECK:STDOUT: >[] stack-push: ExpressionAction pos: 0 `0` (phase_execution.carbon:10)
@@ -52,6 +77,10 @@ fn Main() -> i32 {
 // CHECK:STDOUT: ->> step ValueExpressionAction pos: 1 `0` results: [`0`]  (phase_execution.carbon:10) --->
 // CHECK:STDOUT: <[] stack-pop:  ValueExpressionAction pos: 1 `0` results: [`0`]  (phase_execution.carbon:10)
 // CHECK:STDOUT: ->> step StatementAction pos: 1 `return 0;` results: [`0`]  (phase_execution.carbon:10) --->
+// CHECK:STDOUT: *** statement at (phase_execution.carbon:10)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: return 0;
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: <[] stack-pop:  StatementAction pos: 1 `return 0;` results: [`0`]  (phase_execution.carbon:10)
 // CHECK:STDOUT: <[] stack-pop:  StatementAction pos: 1 `{return 0;}` scope: [] (phase_execution.carbon:11)
 // CHECK:STDOUT: <[] stack-pop:  ScopeAction pos: 0  scope: [] (None)

+ 43 - 0
explorer/testdata/trace/phase_type_checking.carbon

@@ -16,8 +16,20 @@ fn Main() -> i32 {
 // AUTOUPDATE
 
 // CHECK:STDOUT: ********** type checking **********
+// CHECK:STDOUT: *** declaration at (phase_type_checking.carbon:7)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: interface TestInterface {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> declaring `interface TestInterface` (phase_type_checking.carbon:7)
 // CHECK:STDOUT: <<- finished declaring `interface TestInterface` (phase_type_checking.carbon:7)
+// CHECK:STDOUT: *** type checking declaration at (phase_type_checking.carbon:7)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: interface TestInterface {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> checking InterfaceDeclaration `interface TestInterface` (phase_type_checking.carbon:7)
 // CHECK:STDOUT: ->> checking `interface TestInterface` (phase_type_checking.carbon:7)
 // CHECK:STDOUT: ==> impl declarations for `interface TestInterface` (phase_type_checking.carbon:7)
@@ -70,6 +82,16 @@ fn Main() -> i32 {
 // CHECK:STDOUT:     `T` as `interface LeftShiftAssignWith(U = U)` [0; 1, 1, 0],
 // CHECK:STDOUT:     `T` as `interface RightShiftAssignWith(U = U)` [0; 1, 1, 0]]
 // CHECK:STDOUT: <<- finished checking `interface TestInterface` (phase_type_checking.carbon:7)
+// CHECK:STDOUT: *** declaration at (phase_type_checking.carbon:11)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: fn Main ()-> i32 {
+// CHECK:STDOUT: {
+// CHECK:STDOUT: return 0;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> declaring function `Main` (phase_type_checking.carbon:11)
 // CHECK:STDOUT: ->> checking TuplePattern `()` (phase_type_checking.carbon:9)
 // CHECK:STDOUT: ->> checking IntTypeLiteral `i32` (phase_type_checking.carbon:9)
@@ -81,6 +103,16 @@ fn Main() -> i32 {
 // CHECK:STDOUT: ->> step ValueExpressionAction pos: 1 `i32` results: [`i32`]  (phase_type_checking.carbon:9) --->
 // CHECK:STDOUT: <[] stack-pop:  ValueExpressionAction pos: 1 `i32` results: [`i32`]  (phase_type_checking.carbon:9)
 // CHECK:STDOUT: ->> finished declaring function `Main` of type `fn () -> i32` (phase_type_checking.carbon:11)
+// CHECK:STDOUT: *** type checking declaration at (phase_type_checking.carbon:11)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: fn Main ()-> i32 {
+// CHECK:STDOUT: {
+// CHECK:STDOUT: return 0;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> checking FunctionDeclaration `fn Main` (phase_type_checking.carbon:11)
 // CHECK:STDOUT: ->> checking function `Main` (phase_type_checking.carbon:11)
 // CHECK:STDOUT: ==> impl declarations for `fn Main` (phase_type_checking.carbon:11)
@@ -132,7 +164,18 @@ fn Main() -> i32 {
 // CHECK:STDOUT:     `T` as `interface BitXorAssignWith(U = U)` [0; 1, 1, 0],
 // CHECK:STDOUT:     `T` as `interface LeftShiftAssignWith(U = U)` [0; 1, 1, 0],
 // CHECK:STDOUT:     `T` as `interface RightShiftAssignWith(U = U)` [0; 1, 1, 0]]
+// CHECK:STDOUT: *** type checking stmt at (phase_type_checking.carbon:11)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: {
+// CHECK:STDOUT: return 0;
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> checking Block `{return 0;}` (phase_type_checking.carbon:11)
+// CHECK:STDOUT: *** type checking stmt at (phase_type_checking.carbon:10)
+// CHECK:STDOUT: ```
+// CHECK:STDOUT: return 0;
+// CHECK:STDOUT: ```
 // CHECK:STDOUT: ->> checking ReturnExpression `return 0;` (phase_type_checking.carbon:10)
 // CHECK:STDOUT: ->> checking IntLiteral `0` (phase_type_checking.carbon:10)
 // CHECK:STDOUT: ->> finished checking function `Main` (phase_type_checking.carbon:11)