From 418bad939abf464ac03dab0c9044316aa4c33f95 Mon Sep 17 00:00:00 2001 From: Prabhat Sachdeva Date: Fri, 21 Jul 2023 06:48:18 +0530 Subject: [PATCH] Add name resolution information to trace stream (#2986) Adds the following information about name resolution to the trace output: * Name resolution process ``` ** resolving stmt | decl `` () ... ** finished resolving stmt | decl `` () ``` * When a name is added to the static scope ``` --- declared `` as `` in `` () ``` * When a name is resolved ``` --- resolved `` as `` in `` () ``` * Marking a name declared/usable ``` --- marked `` in `` ``` --- explorer/ast/BUILD | 2 + explorer/ast/static_scope.cpp | 42 +++ explorer/ast/static_scope.h | 21 +- explorer/interpreter/BUILD | 1 + explorer/interpreter/exec_program.cpp | 2 +- explorer/interpreter/resolve_names.cpp | 75 +++-- explorer/interpreter/resolve_names.h | 4 +- explorer/trace_testdata/full_trace.carbon | 347 +++++++++++++++++++--- 8 files changed, 435 insertions(+), 59 deletions(-) diff --git a/explorer/ast/BUILD b/explorer/ast/BUILD index 0fecb13ec634..cd2dfad2acc3 100644 --- a/explorer/ast/BUILD +++ b/explorer/ast/BUILD @@ -147,9 +147,11 @@ cc_library( ":ast", "//common:check", "//common:error", + "//common:ostream", "//explorer/common:error_builders", "//explorer/common:nonnull", "//explorer/common:source_location", + "//explorer/common:trace_stream", "@llvm-project//llvm:Support", ], ) diff --git a/explorer/ast/static_scope.cpp b/explorer/ast/static_scope.cpp index 2e0a5b043047..c1910db6965f 100644 --- a/explorer/ast/static_scope.cpp +++ b/explorer/ast/static_scope.cpp @@ -6,7 +6,9 @@ #include +#include "common/ostream.h" #include "explorer/common/error_builders.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/Support/Error.h" namespace Carbon { @@ -23,15 +25,42 @@ auto StaticScope::Add(std::string_view name, ValueNodeView entity, if (static_cast(status) > static_cast(it->second.status)) { it->second.status = status; } + } else { + if (trace_stream_->is_enabled()) { + *trace_stream_ << "--- declared `" << name << "` as `" << entity + << "` in `" << PrintAsID(*this) << "` (" + << entity.base().source_loc() << ")\n"; + } } return Success(); } +void StaticScope::Print(llvm::raw_ostream& out) const { + if (ast_node_) { + ast_node_.value()->Print(out); + } else { + *trace_stream_ << "package"; + } +} + +void StaticScope::PrintID(llvm::raw_ostream& out) const { + if (ast_node_) { + ast_node_.value()->PrintID(out); + } else { + *trace_stream_ << "package"; + } +} + void StaticScope::MarkDeclared(std::string_view name) { auto it = declared_names_.find(name); CARBON_CHECK(it != declared_names_.end()) << name << " not found"; if (it->second.status == NameStatus::KnownButNotDeclared) { it->second.status = NameStatus::DeclaredButNotUsable; + if (trace_stream_->is_enabled()) { + *trace_stream_ << "--- marked `" << name + << "` declared but not usable in `" << PrintAsID(*this) + << "`\n"; + } } } @@ -39,6 +68,10 @@ void StaticScope::MarkUsable(std::string_view name) { auto it = declared_names_.find(name); CARBON_CHECK(it != declared_names_.end()) << name << " not found"; it->second.status = NameStatus::Usable; + if (trace_stream_->is_enabled()) { + *trace_stream_ << "--- marked `" << name << "` usable in `" + << PrintAsID(*this) << "`\n"; + } } auto StaticScope::Resolve(std::string_view name, @@ -94,6 +127,15 @@ auto StaticScope::TryResolveHere(std::string_view name, if (it == declared_names_.end()) { return {std::nullopt}; } + + auto exit_scope_function = llvm::make_scope_exit([&]() { + if (trace_stream_->is_enabled()) { + *trace_stream_ << "--- resolved `" << name << "` as `" + << it->second.entity << "` in `" << PrintAsID(*this) + << "` (" << source_loc << ")\n"; + } + }); + if (allow_undeclared) { return {it->second.entity}; } diff --git a/explorer/ast/static_scope.h b/explorer/ast/static_scope.h index 79da6b2e86a3..746807c38825 100644 --- a/explorer/ast/static_scope.h +++ b/explorer/ast/static_scope.h @@ -12,6 +12,7 @@ #include "explorer/ast/value_node.h" #include "explorer/common/nonnull.h" #include "explorer/common/source_location.h" +#include "explorer/common/trace_stream.h" #include "llvm/ADT/StringMap.h" namespace Carbon { @@ -35,11 +36,17 @@ class StaticScope { }; // Construct a root scope. - StaticScope() = default; + explicit StaticScope(Nonnull trace_stream) + : ast_node_(std::nullopt), trace_stream_(trace_stream) {} // Construct a scope that is nested within the given scope. - explicit StaticScope(Nonnull parent) - : parent_scope_(parent) {} + explicit StaticScope(Nonnull parent, + std::optional> ast_node) + : parent_scope_(parent), + ast_node_(ast_node), + trace_stream_(parent->trace_stream_) {} + + StaticScope() = default; // Defines `name` to be `entity` in this scope, or reports a compilation error // if `name` is already defined to be a different entity in this scope. @@ -48,6 +55,10 @@ class StaticScope { auto Add(std::string_view name, ValueNodeView entity, NameStatus status = NameStatus::Usable) -> ErrorOr; + void Print(llvm::raw_ostream& out) const; + + void PrintID(llvm::raw_ostream& out) const; + // Marks `name` as being past its point of declaration. void MarkDeclared(std::string_view name); // Marks `name` as being completely declared and hence usable. @@ -102,6 +113,10 @@ class StaticScope { // Stores the value node of the BindingPattern of the returned var definition. std::optional returned_var_def_view_; + + std::optional> ast_node_; + + Nonnull trace_stream_; }; } // namespace Carbon diff --git a/explorer/interpreter/BUILD b/explorer/interpreter/BUILD index 94102e9ec057..b2ec4791c7a2 100644 --- a/explorer/interpreter/BUILD +++ b/explorer/interpreter/BUILD @@ -152,6 +152,7 @@ cc_library( "//explorer/ast", "//explorer/ast:static_scope", "//explorer/common:arena", + "//explorer/common:trace_stream", "@llvm-project//llvm:Support", ], ) diff --git a/explorer/interpreter/exec_program.cpp b/explorer/interpreter/exec_program.cpp index debecefc725a..3b066a3d010c 100644 --- a/explorer/interpreter/exec_program.cpp +++ b/explorer/interpreter/exec_program.cpp @@ -45,7 +45,7 @@ auto AnalyzeProgram(Nonnull arena, AST ast, if (trace_stream->is_enabled()) { *trace_stream << "********** resolving names **********\n"; } - CARBON_RETURN_IF_ERROR(ResolveNames(ast)); + CARBON_RETURN_IF_ERROR(ResolveNames(ast, trace_stream)); set_prog_phase.update_phase(ProgramPhase::ControlFlowResolution); if (trace_stream->is_enabled()) { diff --git a/explorer/interpreter/resolve_names.cpp b/explorer/interpreter/resolve_names.cpp index b7b6d7b556a9..6897b8129ebd 100644 --- a/explorer/interpreter/resolve_names.cpp +++ b/explorer/interpreter/resolve_names.cpp @@ -39,6 +39,8 @@ namespace { // bodies. class NameResolver { public: + explicit NameResolver(Nonnull trace_stream) + : trace_stream_(trace_stream) {} enum class ResolveFunctionBodies { // Do not resolve names in function bodies. Skip, @@ -122,6 +124,8 @@ class NameResolver { // Mapping from declarations to the scope in which they expose a name. llvm::DenseMap exposed_name_scopes_; + + Nonnull trace_stream_; }; } // namespace @@ -132,6 +136,7 @@ auto NameResolver::ResolveQualifier(DeclaredName name, -> ErrorOr> { Nonnull scope = &enclosing_scope; std::optional scope_node; + for (const auto& [loc, qualifier] : name.qualifiers()) { // TODO: If we permit qualified names anywhere other than the top level, we // will need to decide whether the first name in the qualifier is looked up @@ -164,9 +169,9 @@ auto NameResolver::AddExposedName(DeclaredName name, ValueNodeView value, // We are just collecting names at this stage, so nothing is marked as // declared yet. Therefore we don't complain if the qualifier contains a // known but not declared namespace name. - CARBON_ASSIGN_OR_RETURN( - Nonnull scope, - ResolveQualifier(name, enclosing_scope, /*allow_undeclared=*/true)); + CARBON_ASSIGN_OR_RETURN(Nonnull scope, + ResolveQualifier(name, enclosing_scope, + /*allow_undeclared=*/true)); CARBON_RETURN_IF_ERROR(scope->Add( name.inner_name(), value, StaticScope::NameStatus::KnownButNotDeclared)); return scope; @@ -183,7 +188,7 @@ auto NameResolver::AddExposedNames(const Declaration& declaration, Nonnull scope, AddExposedName(namespace_decl.name(), &namespace_decl, enclosing_scope, allow_qualified_names)); - namespace_scopes_.try_emplace(&namespace_decl, scope); + namespace_scopes_.try_emplace(&namespace_decl, scope, &namespace_decl); break; } case DeclarationKind::InterfaceDeclaration: @@ -426,7 +431,7 @@ auto NameResolver::ResolveNamesImpl(Expression& expression, &cast(enclosing_dot_self->base())); } // Introduce `.Self` into scope on the right of the `where` keyword. - StaticScope where_scope(&enclosing_scope); + StaticScope where_scope(&enclosing_scope, &where); CARBON_RETURN_IF_ERROR(where_scope.Add(".Self", &where.self_binding())); for (Nonnull clause : where.clauses()) { CARBON_RETURN_IF_ERROR(ResolveNames(*clause, where_scope)); @@ -458,6 +463,7 @@ auto NameResolver::ResolveNamesImpl(Expression& expression, case ExpressionKind::UnimplementedExpression: return ProgramError(expression.source_loc()) << "Unimplemented"; } + return {std::nullopt}; } @@ -495,6 +501,7 @@ auto NameResolver::ResolveNamesImpl(WhereClause& clause, break; } } + return Success(); } @@ -519,7 +526,7 @@ auto NameResolver::ResolveNamesImpl(Pattern& pattern, case PatternKind::GenericBinding: { auto& binding = cast(pattern); // `.Self` is in scope in the context of the type. - StaticScope self_scope(&enclosing_scope); + StaticScope self_scope(&enclosing_scope, &binding); CARBON_RETURN_IF_ERROR(self_scope.Add(".Self", &binding)); CARBON_RETURN_IF_ERROR(ResolveNames(binding.type(), self_scope)); if (binding.name() != AnonymousName) { @@ -555,6 +562,7 @@ auto NameResolver::ResolveNamesImpl(Pattern& pattern, ResolveNames(cast(pattern).binding(), enclosing_scope)); break; } + return Success(); } @@ -568,6 +576,10 @@ auto NameResolver::ResolveNames(Statement& statement, auto NameResolver::ResolveNamesImpl(Statement& statement, StaticScope& enclosing_scope) -> ErrorOr { + if (trace_stream_->is_enabled()) { + *trace_stream_ << "** resolving stmt `" << PrintAsID(statement) << "` (" + << statement.source_loc() << ")\n"; + } switch (statement.kind()) { case StatementKind::ExpressionStatement: CARBON_RETURN_IF_ERROR(ResolveNames( @@ -638,7 +650,7 @@ auto NameResolver::ResolveNamesImpl(Statement& statement, } case StatementKind::Block: { auto& block = cast(statement); - StaticScope block_scope(&enclosing_scope); + StaticScope block_scope(&enclosing_scope, &block); for (Nonnull sub_statement : block.statements()) { CARBON_RETURN_IF_ERROR(ResolveNames(*sub_statement, block_scope)); } @@ -652,8 +664,8 @@ auto NameResolver::ResolveNamesImpl(Statement& statement, break; } case StatementKind::For: { - StaticScope statement_scope(&enclosing_scope); auto& for_stmt = cast(statement); + StaticScope statement_scope(&enclosing_scope, &for_stmt); CARBON_RETURN_IF_ERROR( ResolveNames(for_stmt.loop_target(), statement_scope)); CARBON_RETURN_IF_ERROR( @@ -666,7 +678,7 @@ auto NameResolver::ResolveNamesImpl(Statement& statement, auto& match = cast(statement); CARBON_RETURN_IF_ERROR(ResolveNames(match.expression(), enclosing_scope)); for (Match::Clause& clause : match.clauses()) { - StaticScope clause_scope(&enclosing_scope); + StaticScope clause_scope(&enclosing_scope, &clause.statement()); CARBON_RETURN_IF_ERROR(ResolveNames(clause.pattern(), clause_scope)); CARBON_RETURN_IF_ERROR(ResolveNames(clause.statement(), clause_scope)); } @@ -676,6 +688,13 @@ auto NameResolver::ResolveNamesImpl(Statement& statement, case StatementKind::Continue: break; } + + if (trace_stream_->is_enabled()) { + *trace_stream_ << "** finished resolving stmt `"; + statement.PrintID(trace_stream_->stream()); + *trace_stream_ << "` (" << statement.source_loc() << ")\n"; + } + return Success(); } @@ -712,6 +731,12 @@ auto NameResolver::ResolveNamesImpl(Declaration& declaration, StaticScope& enclosing_scope, ResolveFunctionBodies bodies) -> ErrorOr { + if (trace_stream_->is_enabled()) { + *trace_stream_ << "** resolving decl `"; + declaration.PrintID(trace_stream_->stream()); + *trace_stream_ << "` (" << declaration.source_loc() << ")\n"; + } + switch (declaration.kind()) { case DeclarationKind::NamespaceDeclaration: { auto& namespace_decl = cast(declaration); @@ -726,7 +751,7 @@ auto NameResolver::ResolveNamesImpl(Declaration& declaration, auto& iface = cast(declaration); CARBON_ASSIGN_OR_RETURN(Nonnull scope, ResolveQualifier(iface.name(), enclosing_scope)); - StaticScope iface_scope(scope); + StaticScope iface_scope(scope, &iface); scope->MarkDeclared(iface.name().inner_name()); if (auto params = iface.params()) { CARBON_RETURN_IF_ERROR(ResolveNames(**params, iface_scope)); @@ -741,7 +766,7 @@ auto NameResolver::ResolveNamesImpl(Declaration& declaration, } case DeclarationKind::ImplDeclaration: { auto& impl = cast(declaration); - StaticScope impl_scope(&enclosing_scope); + StaticScope impl_scope(&enclosing_scope, &impl); for (Nonnull binding : impl.deduced_parameters()) { CARBON_RETURN_IF_ERROR(ResolveNames(binding->type(), impl_scope)); CARBON_RETURN_IF_ERROR(impl_scope.Add(binding->name(), binding)); @@ -778,7 +803,7 @@ auto NameResolver::ResolveNamesImpl(Declaration& declaration, : DeclaredName(function.source_loc(), "destructor"); CARBON_ASSIGN_OR_RETURN(Nonnull scope, ResolveQualifier(name, enclosing_scope)); - StaticScope function_scope(scope); + StaticScope function_scope(scope, &function); scope->MarkDeclared(name.inner_name()); for (Nonnull binding : function.deduced_parameters()) { CARBON_RETURN_IF_ERROR(ResolveNames(*binding, function_scope)); @@ -805,7 +830,7 @@ auto NameResolver::ResolveNamesImpl(Declaration& declaration, CARBON_ASSIGN_OR_RETURN( Nonnull scope, ResolveQualifier(class_decl.name(), enclosing_scope)); - StaticScope class_scope(scope); + StaticScope class_scope(scope, &class_decl); scope->MarkDeclared(class_decl.name().inner_name()); if (auto type_params = class_decl.type_params()) { CARBON_RETURN_IF_ERROR(ResolveNames(**type_params, class_scope)); @@ -827,7 +852,7 @@ auto NameResolver::ResolveNamesImpl(Declaration& declaration, CARBON_ASSIGN_OR_RETURN( Nonnull scope, ResolveQualifier(mixin_decl.name(), enclosing_scope)); - StaticScope mixin_scope(scope); + StaticScope mixin_scope(scope, &mixin_decl); scope->MarkDeclared(mixin_decl.name().inner_name()); if (auto params = mixin_decl.params()) { CARBON_RETURN_IF_ERROR(ResolveNames(**params, mixin_scope)); @@ -847,7 +872,7 @@ auto NameResolver::ResolveNamesImpl(Declaration& declaration, auto& choice = cast(declaration); CARBON_ASSIGN_OR_RETURN(Nonnull scope, ResolveQualifier(choice.name(), enclosing_scope)); - StaticScope choice_scope(scope); + StaticScope choice_scope(scope, &choice); scope->MarkDeclared(choice.name().inner_name()); if (auto type_params = choice.type_params()) { CARBON_RETURN_IF_ERROR(ResolveNames(**type_params, choice_scope)); @@ -893,7 +918,7 @@ auto NameResolver::ResolveNamesImpl(Declaration& declaration, } case DeclarationKind::AssociatedConstantDeclaration: { auto& let = cast(declaration); - StaticScope constant_scope(&enclosing_scope); + StaticScope constant_scope(&enclosing_scope, &let); enclosing_scope.MarkDeclared(let.binding().name()); CARBON_RETURN_IF_ERROR(ResolveNames(let.binding(), constant_scope)); enclosing_scope.MarkUsable(let.binding().name()); @@ -924,19 +949,31 @@ auto NameResolver::ResolveNamesImpl(Declaration& declaration, break; } } + + if (trace_stream_->is_enabled()) { + *trace_stream_ << "** finished resolving decl `"; + declaration.PrintID(trace_stream_->stream()); + *trace_stream_ << "` (" << declaration.source_loc() << ")\n"; + } + return Success(); } -auto ResolveNames(AST& ast) -> ErrorOr { +auto ResolveNames(AST& ast, Nonnull trace_stream) + -> ErrorOr { return RunWithExtraStack([&]() -> ErrorOr { - NameResolver resolver; + NameResolver resolver(trace_stream); + SetFileContext set_file_ctx(*trace_stream, std::nullopt); + StaticScope file_scope(trace_stream); - StaticScope file_scope; for (auto* declaration : ast.declarations) { + set_file_ctx.update_source_loc(declaration->source_loc()); CARBON_RETURN_IF_ERROR(resolver.AddExposedNames( *declaration, file_scope, /*allow_qualified_names=*/true)); } + for (auto* declaration : ast.declarations) { + set_file_ctx.update_source_loc(declaration->source_loc()); CARBON_RETURN_IF_ERROR(resolver.ResolveNames( *declaration, file_scope, NameResolver::ResolveFunctionBodies::AfterDeclarations)); diff --git a/explorer/interpreter/resolve_names.h b/explorer/interpreter/resolve_names.h index 01b5a5fa9e3b..7b8be2510db3 100644 --- a/explorer/interpreter/resolve_names.h +++ b/explorer/interpreter/resolve_names.h @@ -7,13 +7,15 @@ #include "explorer/ast/ast.h" #include "explorer/common/arena.h" +#include "explorer/common/trace_stream.h" namespace Carbon { // Resolves names (IdentifierExpressions) in the AST. // On failure, `ast` is left in a partial state and should not be further // processed. -auto ResolveNames(AST& ast) -> ErrorOr; +auto ResolveNames(AST& ast, Nonnull trace_stream) + -> ErrorOr; } // namespace Carbon diff --git a/explorer/trace_testdata/full_trace.carbon b/explorer/trace_testdata/full_trace.carbon index 4a92abf4c1d1..7ac1f24a0a79 100644 --- a/explorer/trace_testdata/full_trace.carbon +++ b/explorer/trace_testdata/full_trace.carbon @@ -6,13 +6,68 @@ // CHECK:STDOUT: ********** source program ********** // CHECK:STDOUT: interface TestInterface { // CHECK:STDOUT: } +// CHECK:STDOUT: namespace N;fn Foo (n: i32)-> i32 { +// CHECK:STDOUT: { +// CHECK:STDOUT: return (n + 1); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: } // CHECK:STDOUT: fn Main ()-> i32 { // CHECK:STDOUT: { -// CHECK:STDOUT: return 0; +// CHECK:STDOUT: return N.Foo(0); // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: ********** resolving names ********** + + +package ExplorerTest api; + +// CHECK:STDOUT: --- declared `TestInterface` as `interface TestInterface` in `package` (full_trace.carbon:[[@LINE+1]]) +interface TestInterface {} + +// CHECK:STDOUT: --- declared `N` as `namespace N` in `package` (full_trace.carbon:[[@LINE+1]]) +namespace N; + +// CHECK:STDOUT: --- resolved `N` as `namespace N` in `package` (full_trace.carbon:[[@LINE+1]]) +fn N.Foo(n: i32) -> i32 { + return n + 1; +// CHECK:STDOUT: --- declared `Foo` as `fn N.Foo` in `namespace N` (full_trace.carbon:[[@LINE+1]]) +} + +fn Main() -> i32 { + return N.Foo(0); +// CHECK:STDOUT: --- declared `Main` as `fn Main` in `package` (full_trace.carbon:[[@LINE+440]]) +// CHECK:STDOUT: ** resolving decl `interface TestInterface` (full_trace.carbon:[[@LINE-14]]) +// CHECK:STDOUT: --- marked `TestInterface` declared but not usable in `package` +// CHECK:STDOUT: --- marked `TestInterface` usable in `package` +// CHECK:STDOUT: --- declared `Self` as `Self` in `interface TestInterface` (full_trace.carbon:[[@LINE-17]]) +// CHECK:STDOUT: ** finished resolving decl `interface TestInterface` (full_trace.carbon:[[@LINE-18]]) +// CHECK:STDOUT: ** resolving decl `namespace N` (full_trace.carbon:[[@LINE-16]]) +// CHECK:STDOUT: --- marked `N` usable in `package` +// CHECK:STDOUT: ** finished resolving decl `namespace N` (full_trace.carbon:[[@LINE-18]]) +// CHECK:STDOUT: ** resolving decl `fn N.Foo` (full_trace.carbon:[[@LINE-13]]) +// CHECK:STDOUT: --- resolved `N` as `namespace N` in `package` (full_trace.carbon:[[@LINE-17]]) +// CHECK:STDOUT: --- marked `Foo` declared but not usable in `namespace N` +// CHECK:STDOUT: --- declared `n` as `n` in `fn N.Foo` (full_trace.carbon:[[@LINE-19]]) +// CHECK:STDOUT: --- marked `Foo` usable in `namespace N` +// CHECK:STDOUT: ** resolving stmt `{return (n + 1);}` (full_trace.carbon:[[@LINE-18]]) +// CHECK:STDOUT: ** resolving stmt `return (n + 1);` (full_trace.carbon:[[@LINE-21]]) +// CHECK:STDOUT: --- resolved `n` as `n` in `fn N.Foo` (full_trace.carbon:[[@LINE-22]]) +// CHECK:STDOUT: ** finished resolving stmt `return (n + 1);` (full_trace.carbon:[[@LINE-23]]) +// CHECK:STDOUT: ** finished resolving stmt `{return (n + 1);}` (full_trace.carbon:[[@LINE-22]]) +// CHECK:STDOUT: ** finished resolving decl `fn N.Foo` (full_trace.carbon:[[@LINE-23]]) +// CHECK:STDOUT: ** resolving decl `fn Main` (full_trace.carbon:[[@LINE+420]]) +// CHECK:STDOUT: --- marked `Main` declared but not usable in `package` +// CHECK:STDOUT: --- marked `Main` usable in `package` +// CHECK:STDOUT: ** resolving stmt `{return N.Foo(0);}` (full_trace.carbon:[[@LINE+417]]) +// CHECK:STDOUT: ** resolving stmt `return N.Foo(0);` (full_trace.carbon:[[@LINE-25]]) +// CHECK:STDOUT: --- resolved `N` as `namespace N` in `package` (full_trace.carbon:[[@LINE-26]]) +// CHECK:STDOUT: --- resolved `Foo` as `fn N.Foo` in `namespace N` (full_trace.carbon:[[@LINE-27]]) +// CHECK:STDOUT: ** finished resolving stmt `return N.Foo(0);` (full_trace.carbon:[[@LINE-28]]) +// CHECK:STDOUT: ** finished resolving stmt `{return N.Foo(0);}` (full_trace.carbon:[[@LINE+412]]) +// CHECK:STDOUT: ** finished resolving decl `fn Main` (full_trace.carbon:[[@LINE+411]]) +// CHECK:STDOUT: --- resolved `Main` as `fn Main` in `package` (:0) // CHECK:STDOUT: ********** resolving control flow ********** // CHECK:STDOUT: ********** type checking ********** // CHECK:STDOUT: ** declaring interface TestInterface @@ -22,6 +77,62 @@ // CHECK:STDOUT: impl declarations:{{ }} // CHECK:STDOUT: impl declarations: bool as interface EqWith(U = bool), i32 as interface EqWith(U = i32), String as interface EqWith(U = String), i32 as interface CompareWith(U = i32), String as interface CompareWith(U = String), i32 as interface LessWith(U = i32), String as interface LessWith(U = String), i32 as interface LessEqWith(U = i32), String as interface LessEqWith(U = String), i32 as interface GreaterWith(U = i32), String as interface GreaterWith(U = String), i32 as interface GreaterEqWith(U = i32), String as interface GreaterEqWith(U = String), i32 as interface Negate, i32 as interface AddWith(U = i32), i32 as interface SubWith(U = i32), i32 as interface MulWith(U = i32), i32 as interface DivWith(U = i32), i32 as interface ModWith(U = i32), i32 as interface BitComplement, i32 as interface BitAndWith(U = i32), i32 as interface BitOrWith(U = i32), i32 as interface BitXorWith(U = i32), i32 as interface LeftShiftWith(U = i32), i32 as interface RightShiftWith(U = i32), i32 as interface Inc, i32 as interface Dec, U as interface __EqualConverter [0], (T1,) as interface As(T = (U1,)) [0, 0, 0; 1, 1, 0, 0, 0], (T1, T2) as interface As(T = (U1, U2)) [0, 0, 0; 0, 0, 1; 1, 1, 0, 0, 0; 1, 1, 0, 0, 1], (T1, U1) as interface EqWith(U = (T2, U2)) [0, 0, 0; 0, 0, 1; 1, 1, 0, 0, 0; 1, 1, 0, 0, 1], (T1, T2, T3) as interface As(T = (U1, U2, U3)) [0, 0, 0; 0, 0, 1; 0, 0, 2; 1, 1, 0, 0, 0; 1, 1, 0, 0, 1; 1, 1, 0, 0, 2], T as interface ImplicitAs(T = U) [0; 1, 1, 0], T as interface As(T = U) [0; 1, 1, 0], T as interface ImplicitAs(T = U) [0; 1, 1, 0], T as interface As(T = U) [0; 1, 1, 0], T as interface AssignWith(U = U) [0; 1, 1, 0], T as interface AddAssignWith(U = U) [0; 1, 1, 0], T as interface SubAssignWith(U = U) [0; 1, 1, 0], T as interface MulAssignWith(U = U) [0; 1, 1, 0], T as interface DivAssignWith(U = U) [0; 1, 1, 0], T as interface ModAssignWith(U = U) [0; 1, 1, 0], T as interface BitAndAssignWith(U = U) [0; 1, 1, 0], T as interface BitOrAssignWith(U = U) [0; 1, 1, 0], T as interface BitXorAssignWith(U = U) [0; 1, 1, 0], T as interface LeftShiftAssignWith(U = U) [0; 1, 1, 0], T as interface RightShiftAssignWith(U = U) [0; 1, 1, 0] // CHECK:STDOUT: ** finished checking interface TestInterface +// CHECK:STDOUT: checking NamespaceDeclaration +// CHECK:STDOUT: ** declaring function Foo +// CHECK:STDOUT: checking TuplePattern (n: i32) +// CHECK:STDOUT: checking BindingPattern n: i32 +// CHECK:STDOUT: checking ExpressionPattern i32 +// CHECK:STDOUT: checking IntTypeLiteral i32 +// CHECK:STDOUT: { +// CHECK:STDOUT: stack:{{ }} +// CHECK:STDOUT: memory:{{ }} +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: i32 .0. ## i32 .1. +// CHECK:STDOUT: memory:{{ }} +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step exp i32 .0. (full_trace.carbon:[[@LINE-61]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: i32 .1. {{[[][[]}}i32]] +// CHECK:STDOUT: memory:{{ }} +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack:{{ }} +// CHECK:STDOUT: memory:{{ }} +// CHECK:STDOUT: } +// CHECK:STDOUT: finished checking tuple pattern field n: i32 +// CHECK:STDOUT: checking IntTypeLiteral i32 +// CHECK:STDOUT: { +// CHECK:STDOUT: stack:{{ }} +// CHECK:STDOUT: memory:{{ }} +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: i32 .0. ## i32 .1. +// CHECK:STDOUT: memory:{{ }} +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step exp i32 .0. (full_trace.carbon:[[@LINE-80]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: i32 .1. {{[[][[]}}i32]] +// CHECK:STDOUT: memory:{{ }} +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack:{{ }} +// CHECK:STDOUT: memory:{{ }} +// CHECK:STDOUT: } +// CHECK:STDOUT: ** finished declaring function Foo of type fn (i32,) -> i32 +// CHECK:STDOUT: checking FunctionDeclaration +// CHECK:STDOUT: ** checking function Foo +// CHECK:STDOUT: impl declarations:{{ }} +// CHECK:STDOUT: impl declarations: bool as interface EqWith(U = bool), i32 as interface EqWith(U = i32), String as interface EqWith(U = String), i32 as interface CompareWith(U = i32), String as interface CompareWith(U = String), i32 as interface LessWith(U = i32), String as interface LessWith(U = String), i32 as interface LessEqWith(U = i32), String as interface LessEqWith(U = String), i32 as interface GreaterWith(U = i32), String as interface GreaterWith(U = String), i32 as interface GreaterEqWith(U = i32), String as interface GreaterEqWith(U = String), i32 as interface Negate, i32 as interface AddWith(U = i32), i32 as interface SubWith(U = i32), i32 as interface MulWith(U = i32), i32 as interface DivWith(U = i32), i32 as interface ModWith(U = i32), i32 as interface BitComplement, i32 as interface BitAndWith(U = i32), i32 as interface BitOrWith(U = i32), i32 as interface BitXorWith(U = i32), i32 as interface LeftShiftWith(U = i32), i32 as interface RightShiftWith(U = i32), i32 as interface Inc, i32 as interface Dec, U as interface __EqualConverter [0], (T1,) as interface As(T = (U1,)) [0, 0, 0; 1, 1, 0, 0, 0], (T1, T2) as interface As(T = (U1, U2)) [0, 0, 0; 0, 0, 1; 1, 1, 0, 0, 0; 1, 1, 0, 0, 1], (T1, U1) as interface EqWith(U = (T2, U2)) [0, 0, 0; 0, 0, 1; 1, 1, 0, 0, 0; 1, 1, 0, 0, 1], (T1, T2, T3) as interface As(T = (U1, U2, U3)) [0, 0, 0; 0, 0, 1; 0, 0, 2; 1, 1, 0, 0, 0; 1, 1, 0, 0, 1; 1, 1, 0, 0, 2], T as interface ImplicitAs(T = U) [0; 1, 1, 0], T as interface As(T = U) [0; 1, 1, 0], T as interface ImplicitAs(T = U) [0; 1, 1, 0], T as interface As(T = U) [0; 1, 1, 0], T as interface AssignWith(U = U) [0; 1, 1, 0], T as interface AddAssignWith(U = U) [0; 1, 1, 0], T as interface SubAssignWith(U = U) [0; 1, 1, 0], T as interface MulAssignWith(U = U) [0; 1, 1, 0], T as interface DivAssignWith(U = U) [0; 1, 1, 0], T as interface ModAssignWith(U = U) [0; 1, 1, 0], T as interface BitAndAssignWith(U = U) [0; 1, 1, 0], T as interface BitOrAssignWith(U = U) [0; 1, 1, 0], T as interface BitXorAssignWith(U = U) [0; 1, 1, 0], T as interface LeftShiftAssignWith(U = U) [0; 1, 1, 0], T as interface RightShiftAssignWith(U = U) [0; 1, 1, 0] +// CHECK:STDOUT: checking Block { +// CHECK:STDOUT: return (n + 1); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: checking ReturnExpression return (n + 1); +// CHECK:STDOUT: checking OperatorExpression (n + 1) +// CHECK:STDOUT: checking IdentifierExpression n +// CHECK:STDOUT: checking IntLiteral 1 +// CHECK:STDOUT: ** finished checking function Foo // CHECK:STDOUT: ** declaring function Main // CHECK:STDOUT: checking TuplePattern () // CHECK:STDOUT: checking IntTypeLiteral i32 @@ -33,13 +144,7 @@ // CHECK:STDOUT: stack: i32 .0. ## i32 .1. // CHECK:STDOUT: memory:{{ }} // CHECK:STDOUT: } - - -package ExplorerTest api; - -interface TestInterface {} - -// CHECK:STDOUT: --- step exp i32 .0. (full_trace.carbon:[[@LINE+53]]) ---> +// CHECK:STDOUT: --- step exp i32 .0. (full_trace.carbon:[[@LINE-109]]) ---> // CHECK:STDOUT: { // CHECK:STDOUT: stack: i32 .1. {{[[][[]}}i32]] // CHECK:STDOUT: memory:{{ }} @@ -54,11 +159,20 @@ interface TestInterface {} // CHECK:STDOUT: impl declarations:{{ }} // CHECK:STDOUT: impl declarations: bool as interface EqWith(U = bool), i32 as interface EqWith(U = i32), String as interface EqWith(U = String), i32 as interface CompareWith(U = i32), String as interface CompareWith(U = String), i32 as interface LessWith(U = i32), String as interface LessWith(U = String), i32 as interface LessEqWith(U = i32), String as interface LessEqWith(U = String), i32 as interface GreaterWith(U = i32), String as interface GreaterWith(U = String), i32 as interface GreaterEqWith(U = i32), String as interface GreaterEqWith(U = String), i32 as interface Negate, i32 as interface AddWith(U = i32), i32 as interface SubWith(U = i32), i32 as interface MulWith(U = i32), i32 as interface DivWith(U = i32), i32 as interface ModWith(U = i32), i32 as interface BitComplement, i32 as interface BitAndWith(U = i32), i32 as interface BitOrWith(U = i32), i32 as interface BitXorWith(U = i32), i32 as interface LeftShiftWith(U = i32), i32 as interface RightShiftWith(U = i32), i32 as interface Inc, i32 as interface Dec, U as interface __EqualConverter [0], (T1,) as interface As(T = (U1,)) [0, 0, 0; 1, 1, 0, 0, 0], (T1, T2) as interface As(T = (U1, U2)) [0, 0, 0; 0, 0, 1; 1, 1, 0, 0, 0; 1, 1, 0, 0, 1], (T1, U1) as interface EqWith(U = (T2, U2)) [0, 0, 0; 0, 0, 1; 1, 1, 0, 0, 0; 1, 1, 0, 0, 1], (T1, T2, T3) as interface As(T = (U1, U2, U3)) [0, 0, 0; 0, 0, 1; 0, 0, 2; 1, 1, 0, 0, 0; 1, 1, 0, 0, 1; 1, 1, 0, 0, 2], T as interface ImplicitAs(T = U) [0; 1, 1, 0], T as interface As(T = U) [0; 1, 1, 0], T as interface ImplicitAs(T = U) [0; 1, 1, 0], T as interface As(T = U) [0; 1, 1, 0], T as interface AssignWith(U = U) [0; 1, 1, 0], T as interface AddAssignWith(U = U) [0; 1, 1, 0], T as interface SubAssignWith(U = U) [0; 1, 1, 0], T as interface MulAssignWith(U = U) [0; 1, 1, 0], T as interface DivAssignWith(U = U) [0; 1, 1, 0], T as interface ModAssignWith(U = U) [0; 1, 1, 0], T as interface BitAndAssignWith(U = U) [0; 1, 1, 0], T as interface BitOrAssignWith(U = U) [0; 1, 1, 0], T as interface BitXorAssignWith(U = U) [0; 1, 1, 0], T as interface LeftShiftAssignWith(U = U) [0; 1, 1, 0], T as interface RightShiftAssignWith(U = U) [0; 1, 1, 0] // CHECK:STDOUT: checking Block { -// CHECK:STDOUT: return 0; +// CHECK:STDOUT: return N.Foo(0); // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: checking ReturnExpression return 0; +// CHECK:STDOUT: checking ReturnExpression return N.Foo(0); +// CHECK:STDOUT: checking CallExpression N.Foo(0) +// CHECK:STDOUT: checking SimpleMemberAccessExpression N.Foo +// CHECK:STDOUT: checking IdentifierExpression Foo +// CHECK:STDOUT: checking TupleLiteral (0) // CHECK:STDOUT: checking IntLiteral 0 +// CHECK:STDOUT: checking call to function of type fn (i32,) -> i32 +// CHECK:STDOUT: with arguments of type: (i32,) +// CHECK:STDOUT: performing argument deduction for bindings:{{ }} +// CHECK:STDOUT: deducing i32 from i32 +// CHECK:STDOUT: deduction succeeded with results: {} // CHECK:STDOUT: ** finished checking function Main // CHECK:STDOUT: checking CallExpression Main() // CHECK:STDOUT: checking IdentifierExpression Main @@ -71,9 +185,15 @@ interface TestInterface {} // CHECK:STDOUT: ********** printing declarations ********** // CHECK:STDOUT: interface TestInterface { // CHECK:STDOUT: } +// CHECK:STDOUT: namespace N;fn Foo (n: i32)-> i32 { +// CHECK:STDOUT: { +// CHECK:STDOUT: return (n + 1); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: } // CHECK:STDOUT: fn Main ()-> i32 { // CHECK:STDOUT: { -// CHECK:STDOUT: return 0; +// CHECK:STDOUT: return N.Foo(0); // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: } @@ -83,7 +203,7 @@ interface TestInterface {} // CHECK:STDOUT: stack:{{ }} // CHECK:STDOUT: memory: 0: Heap{} // CHECK:STDOUT: } -// CHECK:STDOUT: --- step decl interface TestInterface .0. (full_trace.carbon:[[@LINE-46]]) ---> +// CHECK:STDOUT: --- step decl interface TestInterface .0. (full_trace.carbon:[[@LINE-179]]) ---> // CHECK:STDOUT: { // CHECK:STDOUT: stack:{{ }} // CHECK:STDOUT: memory: 0: Heap{} @@ -92,9 +212,25 @@ interface TestInterface {} // CHECK:STDOUT: stack:{{ }} // CHECK:STDOUT: memory: 0: Heap{} // CHECK:STDOUT: } -fn Main() -> i32 { - return 0; -// CHECK:STDOUT: --- step decl fn Main .0. (full_trace.carbon:[[@LINE+106]]) ---> +// CHECK:STDOUT: --- step decl namespace N .0. (full_trace.carbon:[[@LINE-185]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack:{{ }} +// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack:{{ }} +// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step decl fn N.Foo .0. (full_trace.carbon:[[@LINE-188]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack:{{ }} +// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack:{{ }} +// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step decl fn Main .0. (full_trace.carbon:[[@LINE+247]]) ---> // CHECK:STDOUT: { // CHECK:STDOUT: stack:{{ }} // CHECK:STDOUT: memory: 0: Heap{} @@ -141,63 +277,204 @@ fn Main() -> i32 { // CHECK:STDOUT: match pattern () // CHECK:STDOUT: from value expression with value () // CHECK:STDOUT: { -// CHECK:STDOUT: stack: {return 0;} .0. ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: stack: {return N.Foo(0);} .0. ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. // CHECK:STDOUT: memory: 0: Heap{} // CHECK:STDOUT: } -// CHECK:STDOUT: --- step stmt {return 0;} .0. (full_trace.carbon:[[@LINE+56]]) ---> +// CHECK:STDOUT: --- step stmt {return N.Foo(0);} .0. (full_trace.carbon:[[@LINE+197]]) ---> // CHECK:STDOUT: { -// CHECK:STDOUT: stack: return 0; .0. ## {return 0;} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: stack: return N.Foo(0); .0. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. // CHECK:STDOUT: memory: 0: Heap{} // CHECK:STDOUT: } -// CHECK:STDOUT: --- step stmt return 0; .0. (full_trace.carbon:[[@LINE-56]]) ---> +// CHECK:STDOUT: --- step stmt return N.Foo(0); .0. (full_trace.carbon:[[@LINE-249]]) ---> // CHECK:STDOUT: { -// CHECK:STDOUT: stack: 0 .0. ## return 0; .1. ## {return 0;} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: stack: N.Foo(0) .0. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. // CHECK:STDOUT: memory: 0: Heap{} // CHECK:STDOUT: } // CHECK:STDOUT: { -// CHECK:STDOUT: stack: 0 .0. ## 0 .1. ## return 0; .1. ## {return 0;} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: stack: N.Foo(0) .0. ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. // CHECK:STDOUT: memory: 0: Heap{} // CHECK:STDOUT: } -// CHECK:STDOUT: --- step exp 0 .0. (full_trace.carbon:[[@LINE-65]]) ---> +// CHECK:STDOUT: --- step exp N.Foo(0) .0. (full_trace.carbon:[[@LINE-258]]) ---> // CHECK:STDOUT: { -// CHECK:STDOUT: stack: 0 .1. {{[[][[]}}0]] ## return 0; .1. ## {return 0;} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: stack: N.Foo .0. ## N.Foo(0) .1. ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. // CHECK:STDOUT: memory: 0: Heap{} // CHECK:STDOUT: } // CHECK:STDOUT: { -// CHECK:STDOUT: stack: return 0; .1. {{[[][[]}}0]] ## {return 0;} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: stack: N.Foo .0. ## N.Foo .1. ## N.Foo(0) .1. ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. // CHECK:STDOUT: memory: 0: Heap{} // CHECK:STDOUT: } -// CHECK:STDOUT: --- step stmt return 0; .1. (full_trace.carbon:[[@LINE-74]]) ---> +// CHECK:STDOUT: --- step exp N.Foo .0. (full_trace.carbon:[[@LINE-267]]) ---> // CHECK:STDOUT: { -// CHECK:STDOUT: stack: clean up.0. {} ## clean up.0. {} ## Main() .3. {{[[][[]}}fun
, (), 0]] {} ## Main() .1. +// CHECK:STDOUT: stack: Foo .0. ## N.Foo .1. ## N.Foo(0) .1. ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step exp Foo .0. (full_trace.carbon:[[@LINE-272]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: N.Foo .1. {{[[][[]}}fun]] ## N.Foo(0) .1. ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. // CHECK:STDOUT: memory: 0: Heap{} // CHECK:STDOUT: } // CHECK:STDOUT: { -// CHECK:STDOUT: stack: clean up.0. {} ## Main() .3. {{[[][[]}}fun
, (), 0]] {} ## Main() .1. +// CHECK:STDOUT: stack: N.Foo(0) .1. {{[[][[]}}fun]] ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. // CHECK:STDOUT: memory: 0: Heap{} // CHECK:STDOUT: } +// CHECK:STDOUT: --- step exp N.Foo(0) .1. (full_trace.carbon:[[@LINE-281]]) ---> // CHECK:STDOUT: { -// CHECK:STDOUT: stack: Main() .3. {{[[][[]}}fun
, (), 0]] {} ## Main() .1. +// CHECK:STDOUT: stack: (0) .0. ## N.Foo(0) .2. {{[[][[]}}fun]] ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. // CHECK:STDOUT: memory: 0: Heap{} // CHECK:STDOUT: } +// CHECK:STDOUT: --- step exp (0) .0. (full_trace.carbon:[[@LINE-286]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: 0 .0. ## (0) .1. ## N.Foo(0) .2. {{[[][[]}}fun]] ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step exp 0 .0. (full_trace.carbon:[[@LINE-291]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: (0) .1. {{[[][[]}}0]] ## N.Foo(0) .2. {{[[][[]}}fun]] ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step exp (0) .1. (full_trace.carbon:[[@LINE-296]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: N.Foo(0) .2. {{[[][[]}}fun, (0,)]] ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step exp N.Foo(0) .2. (full_trace.carbon:[[@LINE-301]]) ---> +// CHECK:STDOUT: calling function: fun +// CHECK:STDOUT: match pattern (Placeholder,) +// CHECK:STDOUT: from value expression with value (0,) +// CHECK:STDOUT: match pattern Placeholder +// CHECK:STDOUT: from value expression with value 0 +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: {return (n + 1);} .0. ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step stmt {return (n + 1);} .0. (full_trace.carbon:[[@LINE-314]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: return (n + 1); .0. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step stmt return (n + 1); .0. (full_trace.carbon:[[@LINE-321]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: (n + 1) .0. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: (n + 1) .0. ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step exp (n + 1) .0. (full_trace.carbon:[[@LINE-330]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: n .0. ## (n + 1) .1. ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: n .0. ## n .1. ## (n + 1) .1. ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step exp n .0. (full_trace.carbon:[[@LINE-339]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: n .1. {{[[][[]}}0]] ## (n + 1) .1. ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: (n + 1) .1. {{[[][[]}}0]] ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step exp (n + 1) .1. (full_trace.carbon:[[@LINE-348]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: 1 .0. ## (n + 1) .2. {{[[][[]}}0]] ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: 1 .0. ## 1 .1. ## (n + 1) .2. {{[[][[]}}0]] ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step exp 1 .0. (full_trace.carbon:[[@LINE-357]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: 1 .1. {{[[][[]}}1]] ## (n + 1) .2. {{[[][[]}}0]] ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: (n + 1) .2. {{[[][[]}}0, 1]] ## (n + 1) .1. ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step exp (n + 1) .2. (full_trace.carbon:[[@LINE-366]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: (n + 1) .1. {{[[][[]}}1]] ## return (n + 1); .1. ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: return (n + 1); .1. {{[[][[]}}1]] ## {return (n + 1);} .1. {} ## .0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,)]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step stmt return (n + 1); .1. (full_trace.carbon:[[@LINE-375]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: clean up.0. {} ## clean up.0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,), 1]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: clean up.0. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,), 1]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: destroy.0. ## clean up.1. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,), 1]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: clean up.1. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,), 1]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: clean up.2. {n: i32: lval} ## N.Foo(0) .3. {{[[][[]}}fun, (0,), 1]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: N.Foo(0) .3. {{[[][[]}}fun, (0,), 1]] {} ## N.Foo(0) .1. ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step exp N.Foo(0) .3. (full_trace.carbon:[[@LINE-395]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: clean up.0. {} ## N.Foo(0) .1. {{[[][[]}}1]] ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: N.Foo(0) .1. {{[[][[]}}1]] ## return N.Foo(0); .1. ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: return N.Foo(0); .1. {{[[][[]}}1]] ## {return N.Foo(0);} .1. {} ## .0. {} ## Main() .3. {{[[][[]}}fun
, ()]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 +// CHECK:STDOUT: } +// CHECK:STDOUT: --- step stmt return N.Foo(0); .1. (full_trace.carbon:[[@LINE-408]]) ---> +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: clean up.0. {} ## clean up.0. {} ## Main() .3. {{[[][[]}}fun
, (), 1]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: clean up.0. {} ## Main() .3. {{[[][[]}}fun
, (), 1]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 +// CHECK:STDOUT: } +// CHECK:STDOUT: { +// CHECK:STDOUT: stack: Main() .3. {{[[][[]}}fun
, (), 1]] {} ## Main() .1. +// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 +// CHECK:STDOUT: } // CHECK:STDOUT: --- step exp Main() .3. (:0) ---> // CHECK:STDOUT: { -// CHECK:STDOUT: stack: clean up.0. {} ## Main() .1. {{[[][[]}}0]] -// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: stack: clean up.0. {} ## Main() .1. {{[[][[]}}1]] +// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 // CHECK:STDOUT: } // CHECK:STDOUT: { -// CHECK:STDOUT: stack: Main() .1. {{[[][[]}}0]] -// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: stack: Main() .1. {{[[][[]}}1]] +// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 // CHECK:STDOUT: } // CHECK:STDOUT: { // CHECK:STDOUT: stack:{{ }} -// CHECK:STDOUT: memory: 0: Heap{} +// CHECK:STDOUT: memory: 0: Heap{}, 1: !!0 // CHECK:STDOUT: } -// CHECK:STDOUT: interpreter result: 0 +// CHECK:STDOUT: interpreter result: 1 // CHECK:STDOUT: ********** printing timing ********** // CHECK:STDOUT: Time elapsed in ExecProgram: {{[0-9]+}}ms // CHECK:STDOUT: Time elapsed in AnalyzeProgram: {{[0-9]+}}ms // CHECK:STDOUT: Time elapsed in AddPrelude: {{[0-9]+}}ms // CHECK:STDOUT: Time elapsed in Parse: {{[0-9]+}}ms -// CHECK:STDOUT: result: 0 +// CHECK:STDOUT: result: 1 }