Просмотр исходного кода

Rename Ptr<T> to Nonnull<T*> (#832)

Note that ptr.h also includes an enable_if change, to help avoid https://bugs.llvm.org/show_bug.cgi?id=51881
Jon Meow 4 лет назад
Родитель
Сommit
56dc4ae375
35 измененных файлов с 584 добавлено и 535 удалено
  1. 1 1
      executable_semantics/ast/ast.h
  2. 1 1
      executable_semantics/ast/class_definition.h
  3. 1 1
      executable_semantics/ast/declaration.cpp
  4. 15 13
      executable_semantics/ast/declaration.h
  5. 7 5
      executable_semantics/ast/expression.cpp
  6. 34 30
      executable_semantics/ast/expression.h
  7. 8 8
      executable_semantics/ast/expression_test.cpp
  8. 7 7
      executable_semantics/ast/function_definition.h
  9. 3 3
      executable_semantics/ast/member.h
  10. 5 4
      executable_semantics/ast/paren_contents.h
  11. 12 11
      executable_semantics/ast/pattern.cpp
  12. 22 22
      executable_semantics/ast/pattern.h
  13. 8 8
      executable_semantics/ast/pattern_test.cpp
  14. 1 1
      executable_semantics/ast/source_location.h
  15. 59 56
      executable_semantics/ast/statement.h
  16. 3 3
      executable_semantics/common/arena.h
  17. 10 3
      executable_semantics/common/ptr.h
  18. 2 1
      executable_semantics/interpreter/action.cpp
  19. 17 16
      executable_semantics/interpreter/action.h
  20. 7 7
      executable_semantics/interpreter/dictionary.h
  21. 5 4
      executable_semantics/interpreter/exec_program.cpp
  22. 1 1
      executable_semantics/interpreter/exec_program.h
  23. 3 3
      executable_semantics/interpreter/frame.h
  24. 4 3
      executable_semantics/interpreter/heap.cpp
  25. 6 6
      executable_semantics/interpreter/heap.h
  26. 80 75
      executable_semantics/interpreter/interpreter.cpp
  27. 27 25
      executable_semantics/interpreter/interpreter.h
  28. 67 62
      executable_semantics/interpreter/type_checker.cpp
  29. 37 31
      executable_semantics/interpreter/type_checker.h
  30. 30 27
      executable_semantics/interpreter/value.cpp
  31. 45 45
      executable_semantics/interpreter/value.h
  32. 1 1
      executable_semantics/syntax/parse.cpp
  33. 1 1
      executable_semantics/syntax/parse.h
  34. 5 5
      executable_semantics/syntax/parse_and_lex_context.h
  35. 49 45
      executable_semantics/syntax/parser.ypp

+ 1 - 1
executable_semantics/ast/ast.h

@@ -22,7 +22,7 @@ struct AST {
   // Import directives.
   std::vector<LibraryName> imports;
   // The file's ordered declarations.
-  std::vector<Ptr<const Declaration>> declarations;
+  std::vector<Nonnull<const Declaration*>> declarations;
 };
 
 }  // namespace Carbon

+ 1 - 1
executable_semantics/ast/class_definition.h

@@ -16,7 +16,7 @@ namespace Carbon {
 struct ClassDefinition {
   SourceLocation loc;
   std::string name;
-  std::vector<Ptr<Member>> members;
+  std::vector<Nonnull<Member*>> members;
 };
 
 }  // namespace Carbon

+ 1 - 1
executable_semantics/ast/declaration.cpp

@@ -20,7 +20,7 @@ void Declaration::Print(llvm::raw_ostream& out) const {
       const ClassDefinition& class_def =
           cast<ClassDeclaration>(*this).Definition();
       out << "class " << class_def.name << " {\n";
-      for (Ptr<Member> m : class_def.members) {
+      for (Nonnull<Member*> m : class_def.members) {
         out << *m;
       }
       out << "}\n";

+ 15 - 13
executable_semantics/ast/declaration.h

@@ -60,7 +60,7 @@ class Declaration {
 
 class FunctionDeclaration : public Declaration {
  public:
-  FunctionDeclaration(Ptr<const FunctionDefinition> definition)
+  FunctionDeclaration(Nonnull<const FunctionDefinition*> definition)
       : Declaration(Kind::FunctionDeclaration, definition->source_location),
         definition(definition) {}
 
@@ -71,13 +71,13 @@ class FunctionDeclaration : public Declaration {
   auto Definition() const -> const FunctionDefinition& { return *definition; }
 
  private:
-  Ptr<const FunctionDefinition> definition;
+  Nonnull<const FunctionDefinition*> definition;
 };
 
 class ClassDeclaration : public Declaration {
  public:
   ClassDeclaration(SourceLocation loc, std::string name,
-                   std::vector<Ptr<Member>> members)
+                   std::vector<Nonnull<Member*>> members)
       : Declaration(Kind::ClassDeclaration, loc),
         definition({.loc = loc,
                     .name = std::move(name),
@@ -97,7 +97,8 @@ class ChoiceDeclaration : public Declaration {
  public:
   ChoiceDeclaration(
       SourceLocation loc, std::string name,
-      std::vector<std::pair<std::string, Ptr<const Expression>>> alternatives)
+      std::vector<std::pair<std::string, Nonnull<const Expression*>>>
+          alternatives)
       : Declaration(Kind::ChoiceDeclaration, loc),
         name(std::move(name)),
         alternatives(std::move(alternatives)) {}
@@ -107,21 +108,22 @@ class ChoiceDeclaration : public Declaration {
   }
 
   auto Name() const -> const std::string& { return name; }
-  auto Alternatives() const
-      -> const std::vector<std::pair<std::string, Ptr<const Expression>>>& {
+  auto Alternatives() const -> const
+      std::vector<std::pair<std::string, Nonnull<const Expression*>>>& {
     return alternatives;
   }
 
  private:
   std::string name;
-  std::vector<std::pair<std::string, Ptr<const Expression>>> alternatives;
+  std::vector<std::pair<std::string, Nonnull<const Expression*>>> alternatives;
 };
 
 // Global variable definition implements the Declaration concept.
 class VariableDeclaration : public Declaration {
  public:
-  VariableDeclaration(SourceLocation loc, Ptr<const BindingPattern> binding,
-                      Ptr<const Expression> initializer)
+  VariableDeclaration(SourceLocation loc,
+                      Nonnull<const BindingPattern*> binding,
+                      Nonnull<const Expression*> initializer)
       : Declaration(Kind::VariableDeclaration, loc),
         binding(binding),
         initializer(initializer) {}
@@ -130,15 +132,15 @@ class VariableDeclaration : public Declaration {
     return decl->Tag() == Kind::VariableDeclaration;
   }
 
-  auto Binding() const -> Ptr<const BindingPattern> { return binding; }
-  auto Initializer() const -> Ptr<const Expression> { return initializer; }
+  auto Binding() const -> Nonnull<const BindingPattern*> { return binding; }
+  auto Initializer() const -> Nonnull<const Expression*> { return initializer; }
 
  private:
   // TODO: split this into a non-optional name and a type, initialized by
   // a constructor that takes a BindingPattern and handles errors like a
   // missing name.
-  Ptr<const BindingPattern> binding;
-  Ptr<const Expression> initializer;
+  Nonnull<const BindingPattern*> binding;
+  Nonnull<const Expression*> initializer;
 };
 
 }  // namespace Carbon

+ 7 - 5
executable_semantics/ast/expression.cpp

@@ -17,9 +17,10 @@ namespace Carbon {
 using llvm::cast;
 
 auto ExpressionFromParenContents(
-    Ptr<Arena> arena, SourceLocation loc,
-    const ParenContents<Expression>& paren_contents) -> Ptr<const Expression> {
-  std::optional<Ptr<const Expression>> single_term =
+    Nonnull<Arena*> arena, SourceLocation loc,
+    const ParenContents<Expression>& paren_contents)
+    -> Nonnull<const Expression*> {
+  std::optional<Nonnull<const Expression*>> single_term =
       paren_contents.SingleTerm();
   if (single_term.has_value()) {
     return *single_term;
@@ -29,8 +30,9 @@ auto ExpressionFromParenContents(
 }
 
 auto TupleExpressionFromParenContents(
-    Ptr<Arena> arena, SourceLocation loc,
-    const ParenContents<Expression>& paren_contents) -> Ptr<const Expression> {
+    Nonnull<Arena*> arena, SourceLocation loc,
+    const ParenContents<Expression>& paren_contents)
+    -> Nonnull<const Expression*> {
   return arena->New<TupleLiteral>(
       loc, paren_contents.TupleElements<FieldInitializer>(loc));
 }

+ 34 - 30
executable_semantics/ast/expression.h

@@ -63,25 +63,27 @@ class Expression {
 // grouping if their contents permit that interpretation, or as forming a
 // tuple otherwise.
 auto ExpressionFromParenContents(
-    Ptr<Arena> arena, SourceLocation loc,
-    const ParenContents<Expression>& paren_contents) -> Ptr<const Expression>;
+    Nonnull<Arena*> arena, SourceLocation loc,
+    const ParenContents<Expression>& paren_contents)
+    -> Nonnull<const Expression*>;
 
 // Converts paren_contents to an Expression, interpreting the parentheses as
 // forming a tuple.
 auto TupleExpressionFromParenContents(
-    Ptr<Arena> arena, SourceLocation loc,
-    const ParenContents<Expression>& paren_contents) -> Ptr<const Expression>;
+    Nonnull<Arena*> arena, SourceLocation loc,
+    const ParenContents<Expression>& paren_contents)
+    -> Nonnull<const Expression*>;
 
 // A FieldInitializer represents the initialization of a single tuple field.
 struct FieldInitializer {
-  FieldInitializer(std::string name, Ptr<const Expression> expression)
+  FieldInitializer(std::string name, Nonnull<const Expression*> expression)
       : name(std::move(name)), expression(expression) {}
 
   // The field name. Cannot be empty.
   std::string name;
 
   // The expression that initializes the field.
-  Ptr<const Expression> expression;
+  Nonnull<const Expression*> expression;
 };
 
 enum class Operator {
@@ -115,7 +117,7 @@ class IdentifierExpression : public Expression {
 class FieldAccessExpression : public Expression {
  public:
   explicit FieldAccessExpression(SourceLocation loc,
-                                 Ptr<const Expression> aggregate,
+                                 Nonnull<const Expression*> aggregate,
                                  std::string field)
       : Expression(Kind::FieldAccessExpression, loc),
         aggregate(aggregate),
@@ -125,18 +127,19 @@ class FieldAccessExpression : public Expression {
     return exp->Tag() == Kind::FieldAccessExpression;
   }
 
-  auto Aggregate() const -> Ptr<const Expression> { return aggregate; }
+  auto Aggregate() const -> Nonnull<const Expression*> { return aggregate; }
   auto Field() const -> const std::string& { return field; }
 
  private:
-  Ptr<const Expression> aggregate;
+  Nonnull<const Expression*> aggregate;
   std::string field;
 };
 
 class IndexExpression : public Expression {
  public:
-  explicit IndexExpression(SourceLocation loc, Ptr<const Expression> aggregate,
-                           Ptr<const Expression> offset)
+  explicit IndexExpression(SourceLocation loc,
+                           Nonnull<const Expression*> aggregate,
+                           Nonnull<const Expression*> offset)
       : Expression(Kind::IndexExpression, loc),
         aggregate(aggregate),
         offset(offset) {}
@@ -145,12 +148,12 @@ class IndexExpression : public Expression {
     return exp->Tag() == Kind::IndexExpression;
   }
 
-  auto Aggregate() const -> Ptr<const Expression> { return aggregate; }
-  auto Offset() const -> Ptr<const Expression> { return offset; }
+  auto Aggregate() const -> Nonnull<const Expression*> { return aggregate; }
+  auto Offset() const -> Nonnull<const Expression*> { return offset; }
 
  private:
-  Ptr<const Expression> aggregate;
-  Ptr<const Expression> offset;
+  Nonnull<const Expression*> aggregate;
+  Nonnull<const Expression*> offset;
 };
 
 class IntLiteral : public Expression {
@@ -230,7 +233,7 @@ class PrimitiveOperatorExpression : public Expression {
  public:
   explicit PrimitiveOperatorExpression(
       SourceLocation loc, Operator op,
-      std::vector<Ptr<const Expression>> arguments)
+      std::vector<Nonnull<const Expression*>> arguments)
       : Expression(Kind::PrimitiveOperatorExpression, loc),
         op(op),
         arguments(std::move(arguments)) {}
@@ -240,19 +243,20 @@ class PrimitiveOperatorExpression : public Expression {
   }
 
   auto Op() const -> Operator { return op; }
-  auto Arguments() const -> const std::vector<Ptr<const Expression>>& {
+  auto Arguments() const -> const std::vector<Nonnull<const Expression*>>& {
     return arguments;
   }
 
  private:
   Operator op;
-  std::vector<Ptr<const Expression>> arguments;
+  std::vector<Nonnull<const Expression*>> arguments;
 };
 
 class CallExpression : public Expression {
  public:
-  explicit CallExpression(SourceLocation loc, Ptr<const Expression> function,
-                          Ptr<const Expression> argument)
+  explicit CallExpression(SourceLocation loc,
+                          Nonnull<const Expression*> function,
+                          Nonnull<const Expression*> argument)
       : Expression(Kind::CallExpression, loc),
         function(function),
         argument(argument) {}
@@ -261,19 +265,19 @@ class CallExpression : public Expression {
     return exp->Tag() == Kind::CallExpression;
   }
 
-  auto Function() const -> Ptr<const Expression> { return function; }
-  auto Argument() const -> Ptr<const Expression> { return argument; }
+  auto Function() const -> Nonnull<const Expression*> { return function; }
+  auto Argument() const -> Nonnull<const Expression*> { return argument; }
 
  private:
-  Ptr<const Expression> function;
-  Ptr<const Expression> argument;
+  Nonnull<const Expression*> function;
+  Nonnull<const Expression*> argument;
 };
 
 class FunctionTypeLiteral : public Expression {
  public:
   explicit FunctionTypeLiteral(SourceLocation loc,
-                               Ptr<const Expression> parameter,
-                               Ptr<const Expression> return_type,
+                               Nonnull<const Expression*> parameter,
+                               Nonnull<const Expression*> return_type,
                                bool is_omitted_return_type)
       : Expression(Kind::FunctionTypeLiteral, loc),
         parameter(parameter),
@@ -284,13 +288,13 @@ class FunctionTypeLiteral : public Expression {
     return exp->Tag() == Kind::FunctionTypeLiteral;
   }
 
-  auto Parameter() const -> Ptr<const Expression> { return parameter; }
-  auto ReturnType() const -> Ptr<const Expression> { return return_type; }
+  auto Parameter() const -> Nonnull<const Expression*> { return parameter; }
+  auto ReturnType() const -> Nonnull<const Expression*> { return return_type; }
   auto IsOmittedReturnType() const -> bool { return is_omitted_return_type; }
 
  private:
-  Ptr<const Expression> parameter;
-  Ptr<const Expression> return_type;
+  Nonnull<const Expression*> parameter;
+  Nonnull<const Expression*> return_type;
   bool is_omitted_return_type;
 };
 

+ 8 - 8
executable_semantics/ast/expression_test.cpp

@@ -38,7 +38,7 @@ class ExpressionTest : public ::testing::Test {
 TEST_F(ExpressionTest, EmptyAsExpression) {
   ParenContents<Expression> contents = {.elements = {},
                                         .has_trailing_comma = false};
-  Ptr<const Expression> expression =
+  Nonnull<const Expression*> expression =
       ExpressionFromParenContents(&arena, FakeSourceLoc(1), contents);
   EXPECT_EQ(expression->SourceLoc(), FakeSourceLoc(1));
   ASSERT_EQ(expression->Tag(), Expression::Kind::TupleLiteral);
@@ -48,7 +48,7 @@ TEST_F(ExpressionTest, EmptyAsExpression) {
 TEST_F(ExpressionTest, EmptyAsTuple) {
   ParenContents<Expression> contents = {.elements = {},
                                         .has_trailing_comma = false};
-  Ptr<const Expression> tuple =
+  Nonnull<const Expression*> tuple =
       TupleExpressionFromParenContents(&arena, FakeSourceLoc(1), contents);
   EXPECT_EQ(tuple->SourceLoc(), FakeSourceLoc(1));
   ASSERT_EQ(tuple->Tag(), Expression::Kind::TupleLiteral);
@@ -67,7 +67,7 @@ TEST_F(ExpressionTest, UnaryNoCommaAsExpression) {
                     .term = arena.New<IntLiteral>(FakeSourceLoc(2), 42)}},
       .has_trailing_comma = false};
 
-  Ptr<const Expression> expression =
+  Nonnull<const Expression*> expression =
       ExpressionFromParenContents(&arena, FakeSourceLoc(1), contents);
   EXPECT_EQ(expression->SourceLoc(), FakeSourceLoc(2));
   ASSERT_EQ(expression->Tag(), Expression::Kind::IntLiteral);
@@ -79,7 +79,7 @@ TEST_F(ExpressionTest, UnaryNoCommaAsTuple) {
                     .term = arena.New<IntLiteral>(FakeSourceLoc(2), 42)}},
       .has_trailing_comma = false};
 
-  Ptr<const Expression> tuple =
+  Nonnull<const Expression*> tuple =
       TupleExpressionFromParenContents(&arena, FakeSourceLoc(1), contents);
   EXPECT_EQ(tuple->SourceLoc(), FakeSourceLoc(1));
   ASSERT_EQ(tuple->Tag(), Expression::Kind::TupleLiteral);
@@ -93,7 +93,7 @@ TEST_F(ExpressionTest, UnaryWithCommaAsExpression) {
                     .term = arena.New<IntLiteral>(FakeSourceLoc(2), 42)}},
       .has_trailing_comma = true};
 
-  Ptr<const Expression> expression =
+  Nonnull<const Expression*> expression =
       ExpressionFromParenContents(&arena, FakeSourceLoc(1), contents);
   EXPECT_EQ(expression->SourceLoc(), FakeSourceLoc(1));
   ASSERT_EQ(expression->Tag(), Expression::Kind::TupleLiteral);
@@ -107,7 +107,7 @@ TEST_F(ExpressionTest, UnaryWithCommaAsTuple) {
                     .term = arena.New<IntLiteral>(FakeSourceLoc(2), 42)}},
       .has_trailing_comma = true};
 
-  Ptr<const Expression> tuple =
+  Nonnull<const Expression*> tuple =
       TupleExpressionFromParenContents(&arena, FakeSourceLoc(1), contents);
   EXPECT_EQ(tuple->SourceLoc(), FakeSourceLoc(1));
   ASSERT_EQ(tuple->Tag(), Expression::Kind::TupleLiteral);
@@ -123,7 +123,7 @@ TEST_F(ExpressionTest, BinaryAsExpression) {
                     .term = arena.New<IntLiteral>(FakeSourceLoc(3), 42)}},
       .has_trailing_comma = true};
 
-  Ptr<const Expression> expression =
+  Nonnull<const Expression*> expression =
       ExpressionFromParenContents(&arena, FakeSourceLoc(1), contents);
   EXPECT_EQ(expression->SourceLoc(), FakeSourceLoc(1));
   ASSERT_EQ(expression->Tag(), Expression::Kind::TupleLiteral);
@@ -139,7 +139,7 @@ TEST_F(ExpressionTest, BinaryAsTuple) {
                     .term = arena.New<IntLiteral>(FakeSourceLoc(3), 42)}},
       .has_trailing_comma = true};
 
-  Ptr<const Expression> tuple =
+  Nonnull<const Expression*> tuple =
       TupleExpressionFromParenContents(&arena, FakeSourceLoc(1), contents);
   EXPECT_EQ(tuple->SourceLoc(), FakeSourceLoc(1));
   ASSERT_EQ(tuple->Tag(), Expression::Kind::TupleLiteral);

+ 7 - 7
executable_semantics/ast/function_definition.h

@@ -18,16 +18,16 @@ namespace Carbon {
 //   For now, only generic parameters are supported.
 struct GenericBinding {
   std::string name;
-  Ptr<const Expression> type;
+  Nonnull<const Expression*> type;
 };
 
 struct FunctionDefinition {
   FunctionDefinition(SourceLocation source_location, std::string name,
                      std::vector<GenericBinding> deduced_params,
-                     Ptr<const TuplePattern> param_pattern,
-                     Ptr<const Pattern> return_type,
+                     Nonnull<const TuplePattern*> param_pattern,
+                     Nonnull<const Pattern*> return_type,
                      bool is_omitted_return_type,
-                     std::optional<Ptr<const Statement>> body)
+                     std::optional<Nonnull<const Statement*>> body)
       : source_location(source_location),
         name(std::move(name)),
         deduced_parameters(deduced_params),
@@ -43,10 +43,10 @@ struct FunctionDefinition {
   SourceLocation source_location;
   std::string name;
   std::vector<GenericBinding> deduced_parameters;
-  Ptr<const TuplePattern> param_pattern;
-  Ptr<const Pattern> return_type;
+  Nonnull<const TuplePattern*> param_pattern;
+  Nonnull<const Pattern*> return_type;
   bool is_omitted_return_type;
-  std::optional<Ptr<const Statement>> body;
+  std::optional<Nonnull<const Statement*>> body;
 };
 
 }  // namespace Carbon

+ 3 - 3
executable_semantics/ast/member.h

@@ -51,20 +51,20 @@ class Member {
 
 class FieldMember : public Member {
  public:
-  FieldMember(SourceLocation loc, Ptr<const BindingPattern> binding)
+  FieldMember(SourceLocation loc, Nonnull<const BindingPattern*> binding)
       : Member(Kind::FieldMember, loc), binding(binding) {}
 
   static auto classof(const Member* member) -> bool {
     return member->Tag() == Kind::FieldMember;
   }
 
-  auto Binding() const -> Ptr<const BindingPattern> { return binding; }
+  auto Binding() const -> Nonnull<const BindingPattern*> { return binding; }
 
  private:
   // TODO: split this into a non-optional name and a type, initialized by
   // a constructor that takes a BindingPattern and handles errors like a
   // missing name.
-  Ptr<const BindingPattern> binding;
+  Nonnull<const BindingPattern*> binding;
 };
 
 }  // namespace Carbon

+ 5 - 4
executable_semantics/ast/paren_contents.h

@@ -28,16 +28,16 @@ template <typename Term>
 struct ParenContents {
   struct Element {
     std::optional<std::string> name;
-    Ptr<const Term> term;
+    Nonnull<const Term*> term;
   };
 
   // If this object represents a single term, with no name and no trailing
   // comma, this method returns that term. This typically means the parentheses
   // can be interpreted as grouping.
-  auto SingleTerm() const -> std::optional<Ptr<const Term>>;
+  auto SingleTerm() const -> std::optional<Nonnull<const Term*>>;
 
   // Converts `elements` to std::vector<TupleElement>. TupleElement must
-  // have a constructor that takes a std::string and a Ptr<const Term>.
+  // have a constructor that takes a std::string and a Nonnull<const Term*>.
   //
   // TODO: Find a way to deduce TupleElement from Term.
   template <typename TupleElement>
@@ -50,7 +50,8 @@ struct ParenContents {
 // Implementation details only below here.
 
 template <typename Term>
-auto ParenContents<Term>::SingleTerm() const -> std::optional<Ptr<const Term>> {
+auto ParenContents<Term>::SingleTerm() const
+    -> std::optional<Nonnull<const Term*>> {
   if (elements.size() == 1 && !elements.front().name.has_value() &&
       !has_trailing_comma) {
     return elements.front().term;

+ 12 - 11
executable_semantics/ast/pattern.cpp

@@ -54,8 +54,8 @@ void Pattern::Print(llvm::raw_ostream& out) const {
   }
 }
 
-TuplePattern::TuplePattern(Ptr<Arena> arena,
-                           Ptr<const Expression> tuple_literal)
+TuplePattern::TuplePattern(Nonnull<Arena*> arena,
+                           Nonnull<const Expression*> tuple_literal)
     : Pattern(Kind::TuplePattern, tuple_literal->SourceLoc()) {
   const auto& tuple = cast<TupleLiteral>(*tuple_literal);
   for (const FieldInitializer& init : tuple.Fields()) {
@@ -64,10 +64,11 @@ TuplePattern::TuplePattern(Ptr<Arena> arena,
   }
 }
 
-auto PatternFromParenContents(Ptr<Arena> arena, SourceLocation loc,
+auto PatternFromParenContents(Nonnull<Arena*> arena, SourceLocation loc,
                               const ParenContents<Pattern>& paren_contents)
-    -> Ptr<const Pattern> {
-  std::optional<Ptr<const Pattern>> single_term = paren_contents.SingleTerm();
+    -> Nonnull<const Pattern*> {
+  std::optional<Nonnull<const Pattern*>> single_term =
+      paren_contents.SingleTerm();
   if (single_term.has_value()) {
     return *single_term;
   } else {
@@ -75,9 +76,9 @@ auto PatternFromParenContents(Ptr<Arena> arena, SourceLocation loc,
   }
 }
 
-auto TuplePatternFromParenContents(Ptr<Arena> arena, SourceLocation loc,
+auto TuplePatternFromParenContents(Nonnull<Arena*> arena, SourceLocation loc,
                                    const ParenContents<Pattern>& paren_contents)
-    -> Ptr<const TuplePattern> {
+    -> Nonnull<const TuplePattern*> {
   return arena->New<TuplePattern>(
       loc, paren_contents.TupleElements<TuplePattern::Field>(loc));
 }
@@ -86,7 +87,7 @@ auto TuplePatternFromParenContents(Ptr<Arena> arena, SourceLocation loc,
 // error for incorrect expressions, rather than letting a default cast error
 // apply.
 static const FieldAccessExpression& RequireFieldAccess(
-    Ptr<const Expression> alternative) {
+    Nonnull<const Expression*> alternative) {
   if (alternative->Tag() != Expression::Kind::FieldAccessExpression) {
     FATAL_PROGRAM_ERROR(alternative->SourceLoc())
         << "Alternative pattern must have the form of a field access.";
@@ -95,14 +96,14 @@ static const FieldAccessExpression& RequireFieldAccess(
 }
 
 AlternativePattern::AlternativePattern(SourceLocation loc,
-                                       Ptr<const Expression> alternative,
-                                       Ptr<const TuplePattern> arguments)
+                                       Nonnull<const Expression*> alternative,
+                                       Nonnull<const TuplePattern*> arguments)
     : Pattern(Kind::AlternativePattern, loc),
       choice_type(RequireFieldAccess(alternative).Aggregate()),
       alternative_name(RequireFieldAccess(alternative).Field()),
       arguments(arguments) {}
 
-auto ParenExpressionToParenPattern(Ptr<Arena> arena,
+auto ParenExpressionToParenPattern(Nonnull<Arena*> arena,
                                    const ParenContents<Expression>& contents)
     -> ParenContents<Pattern> {
   ParenContents<Pattern> result = {

+ 22 - 22
executable_semantics/ast/pattern.h

@@ -71,7 +71,7 @@ class AutoPattern : public Pattern {
 class BindingPattern : public Pattern {
  public:
   BindingPattern(SourceLocation loc, std::optional<std::string> name,
-                 Ptr<const Pattern> type)
+                 Nonnull<const Pattern*> type)
       : Pattern(Kind::BindingPattern, loc), name(std::move(name)), type(type) {}
 
   static auto classof(const Pattern* pattern) -> bool {
@@ -82,11 +82,11 @@ class BindingPattern : public Pattern {
   auto Name() const -> const std::optional<std::string>& { return name; }
 
   // The pattern specifying the type of values that this pattern matches.
-  auto Type() const -> Ptr<const Pattern> { return type; }
+  auto Type() const -> Nonnull<const Pattern*> { return type; }
 
  private:
   std::optional<std::string> name;
-  Ptr<const Pattern> type;
+  Nonnull<const Pattern*> type;
 };
 
 // A pattern that matches a tuple value field-wise.
@@ -94,14 +94,14 @@ class TuplePattern : public Pattern {
  public:
   // Represents a portion of a tuple pattern corresponding to a single field.
   struct Field {
-    Field(std::string name, Ptr<const Pattern> pattern)
+    Field(std::string name, Nonnull<const Pattern*> pattern)
         : name(std::move(name)), pattern(pattern) {}
 
     // The field name. Cannot be empty
     std::string name;
 
     // The pattern the field must match.
-    Ptr<const Pattern> pattern;
+    Nonnull<const Pattern*> pattern;
   };
 
   TuplePattern(SourceLocation loc, std::vector<Field> fields)
@@ -111,7 +111,7 @@ class TuplePattern : public Pattern {
   // ExpressionPattern.
   //
   // REQUIRES: tuple_literal->Tag() == Expression::Kind::TupleLiteral
-  TuplePattern(Ptr<Arena> arena, Ptr<const Expression> tuple_literal);
+  TuplePattern(Nonnull<Arena*> arena, Nonnull<const Expression*> tuple_literal);
 
   static auto classof(const Pattern* pattern) -> bool {
     return pattern->Tag() == Kind::TuplePattern;
@@ -126,19 +126,19 @@ class TuplePattern : public Pattern {
 // Converts paren_contents to a Pattern, interpreting the parentheses as
 // grouping if their contents permit that interpretation, or as forming a
 // tuple otherwise.
-auto PatternFromParenContents(Ptr<Arena> arena, SourceLocation loc,
+auto PatternFromParenContents(Nonnull<Arena*> arena, SourceLocation loc,
                               const ParenContents<Pattern>& paren_contents)
-    -> Ptr<const Pattern>;
+    -> Nonnull<const Pattern*>;
 
 // Converts paren_contents to a TuplePattern, interpreting the parentheses as
 // forming a tuple.
-auto TuplePatternFromParenContents(Ptr<Arena> arena, SourceLocation loc,
+auto TuplePatternFromParenContents(Nonnull<Arena*> arena, SourceLocation loc,
                                    const ParenContents<Pattern>& paren_contents)
-    -> Ptr<const TuplePattern>;
+    -> Nonnull<const TuplePattern*>;
 
 // Converts `contents` to ParenContents<Pattern> by replacing each Expression
 // with an ExpressionPattern.
-auto ParenExpressionToParenPattern(Ptr<Arena> arena,
+auto ParenExpressionToParenPattern(Nonnull<Arena*> arena,
                                    const ParenContents<Expression>& contents)
     -> ParenContents<Pattern>;
 
@@ -148,9 +148,9 @@ class AlternativePattern : public Pattern {
   // Constructs an AlternativePattern that matches a value of the type
   // specified by choice_type if it represents an alternative named
   // alternative_name, and its arguments match `arguments`.
-  AlternativePattern(SourceLocation loc, Ptr<const Expression> choice_type,
+  AlternativePattern(SourceLocation loc, Nonnull<const Expression*> choice_type,
                      std::string alternative_name,
-                     Ptr<const TuplePattern> arguments)
+                     Nonnull<const TuplePattern*> arguments)
       : Pattern(Kind::AlternativePattern, loc),
         choice_type(choice_type),
         alternative_name(std::move(alternative_name)),
@@ -158,30 +158,30 @@ class AlternativePattern : public Pattern {
 
   // Constructs an AlternativePattern that matches the alternative specified
   // by `alternative`, if its arguments match `arguments`.
-  AlternativePattern(SourceLocation loc, Ptr<const Expression> alternative,
-                     Ptr<const TuplePattern> arguments);
+  AlternativePattern(SourceLocation loc, Nonnull<const Expression*> alternative,
+                     Nonnull<const TuplePattern*> arguments);
 
   static auto classof(const Pattern* pattern) -> bool {
     return pattern->Tag() == Kind::AlternativePattern;
   }
 
-  auto ChoiceType() const -> Ptr<const Expression> { return choice_type; }
+  auto ChoiceType() const -> Nonnull<const Expression*> { return choice_type; }
   auto AlternativeName() const -> const std::string& {
     return alternative_name;
   }
-  auto Arguments() const -> Ptr<const TuplePattern> { return arguments; }
+  auto Arguments() const -> Nonnull<const TuplePattern*> { return arguments; }
 
  private:
-  Ptr<const Expression> choice_type;
+  Nonnull<const Expression*> choice_type;
   std::string alternative_name;
-  Ptr<const TuplePattern> arguments;
+  Nonnull<const TuplePattern*> arguments;
 };
 
 // A pattern that matches a value if it is equal to the value of a given
 // expression.
 class ExpressionPattern : public Pattern {
  public:
-  ExpressionPattern(Ptr<const Expression> expression)
+  ExpressionPattern(Nonnull<const Expression*> expression)
       : Pattern(Kind::ExpressionPattern, expression->SourceLoc()),
         expression(expression) {}
 
@@ -189,10 +189,10 @@ class ExpressionPattern : public Pattern {
     return pattern->Tag() == Kind::ExpressionPattern;
   }
 
-  auto Expression() const -> Ptr<const Expression> { return expression; }
+  auto Expression() const -> Nonnull<const Expression*> { return expression; }
 
  private:
-  Ptr<const Carbon::Expression> expression;
+  Nonnull<const Carbon::Expression*> expression;
 };
 
 }  // namespace Carbon

+ 8 - 8
executable_semantics/ast/pattern_test.cpp

@@ -37,7 +37,7 @@ class PatternTest : public ::testing::Test {
 TEST_F(PatternTest, EmptyAsPattern) {
   ParenContents<Pattern> contents = {.elements = {},
                                      .has_trailing_comma = false};
-  Ptr<const Pattern> pattern =
+  Nonnull<const Pattern*> pattern =
       PatternFromParenContents(&arena, FakeSourceLoc(1), contents);
   EXPECT_EQ(pattern->SourceLoc(), FakeSourceLoc(1));
   ASSERT_TRUE(isa<TuplePattern>(*pattern));
@@ -47,7 +47,7 @@ TEST_F(PatternTest, EmptyAsPattern) {
 TEST_F(PatternTest, EmptyAsTuplePattern) {
   ParenContents<Pattern> contents = {.elements = {},
                                      .has_trailing_comma = false};
-  Ptr<const TuplePattern> tuple =
+  Nonnull<const TuplePattern*> tuple =
       TuplePatternFromParenContents(&arena, FakeSourceLoc(1), contents);
   EXPECT_EQ(tuple->SourceLoc(), FakeSourceLoc(1));
   EXPECT_THAT(tuple->Fields(), IsEmpty());
@@ -65,7 +65,7 @@ TEST_F(PatternTest, UnaryNoCommaAsPattern) {
                     .term = arena.New<AutoPattern>(FakeSourceLoc(2))}},
       .has_trailing_comma = false};
 
-  Ptr<const Pattern> pattern =
+  Nonnull<const Pattern*> pattern =
       PatternFromParenContents(&arena, FakeSourceLoc(1), contents);
   EXPECT_EQ(pattern->SourceLoc(), FakeSourceLoc(2));
   ASSERT_TRUE(isa<AutoPattern>(*pattern));
@@ -77,7 +77,7 @@ TEST_F(PatternTest, UnaryNoCommaAsTuplePattern) {
                     .term = arena.New<AutoPattern>(FakeSourceLoc(2))}},
       .has_trailing_comma = false};
 
-  Ptr<const TuplePattern> tuple =
+  Nonnull<const TuplePattern*> tuple =
       TuplePatternFromParenContents(&arena, FakeSourceLoc(1), contents);
   EXPECT_EQ(tuple->SourceLoc(), FakeSourceLoc(1));
   EXPECT_THAT(tuple->Fields(), ElementsAre(AutoFieldNamed("0")));
@@ -89,7 +89,7 @@ TEST_F(PatternTest, UnaryWithCommaAsPattern) {
                     .term = arena.New<AutoPattern>(FakeSourceLoc(2))}},
       .has_trailing_comma = true};
 
-  Ptr<const Pattern> pattern =
+  Nonnull<const Pattern*> pattern =
       PatternFromParenContents(&arena, FakeSourceLoc(1), contents);
   EXPECT_EQ(pattern->SourceLoc(), FakeSourceLoc(1));
   ASSERT_TRUE(isa<TuplePattern>(*pattern));
@@ -103,7 +103,7 @@ TEST_F(PatternTest, UnaryWithCommaAsTuplePattern) {
                     .term = arena.New<AutoPattern>(FakeSourceLoc(2))}},
       .has_trailing_comma = true};
 
-  Ptr<const TuplePattern> tuple =
+  Nonnull<const TuplePattern*> tuple =
       TuplePatternFromParenContents(&arena, FakeSourceLoc(1), contents);
   EXPECT_EQ(tuple->SourceLoc(), FakeSourceLoc(1));
   EXPECT_THAT(tuple->Fields(), ElementsAre(AutoFieldNamed("0")));
@@ -117,7 +117,7 @@ TEST_F(PatternTest, BinaryAsPattern) {
                     .term = arena.New<AutoPattern>(FakeSourceLoc(2))}},
       .has_trailing_comma = true};
 
-  Ptr<const Pattern> pattern =
+  Nonnull<const Pattern*> pattern =
       PatternFromParenContents(&arena, FakeSourceLoc(1), contents);
   EXPECT_EQ(pattern->SourceLoc(), FakeSourceLoc(1));
   ASSERT_TRUE(isa<TuplePattern>(*pattern));
@@ -133,7 +133,7 @@ TEST_F(PatternTest, BinaryAsTuplePattern) {
                     .term = arena.New<AutoPattern>(FakeSourceLoc(2))}},
       .has_trailing_comma = true};
 
-  Ptr<const TuplePattern> tuple =
+  Nonnull<const TuplePattern*> tuple =
       TuplePatternFromParenContents(&arena, FakeSourceLoc(1), contents);
   EXPECT_EQ(tuple->SourceLoc(), FakeSourceLoc(1));
   EXPECT_THAT(tuple->Fields(),

+ 1 - 1
executable_semantics/ast/source_location.h

@@ -18,7 +18,7 @@ class SourceLocation {
   // The filename should be eternal or arena-allocated to eliminate copies.
   SourceLocation(const char* filename, int line_num)
       : filename(filename), line_num(line_num) {}
-  SourceLocation(Ptr<const std::string> filename, int line_num)
+  SourceLocation(Nonnull<const std::string*> filename, int line_num)
       : filename(filename->c_str()), line_num(line_num) {}
 
   SourceLocation(const SourceLocation&) = default;

+ 59 - 56
executable_semantics/ast/statement.h

@@ -58,60 +58,60 @@ class Statement {
 
 class ExpressionStatement : public Statement {
  public:
-  ExpressionStatement(SourceLocation loc, Ptr<const Expression> exp)
+  ExpressionStatement(SourceLocation loc, Nonnull<const Expression*> exp)
       : Statement(Kind::ExpressionStatement, loc), exp(exp) {}
 
   static auto classof(const Statement* stmt) -> bool {
     return stmt->Tag() == Kind::ExpressionStatement;
   }
 
-  auto Exp() const -> Ptr<const Expression> { return exp; }
+  auto Exp() const -> Nonnull<const Expression*> { return exp; }
 
  private:
-  Ptr<const Expression> exp;
+  Nonnull<const Expression*> exp;
 };
 
 class Assign : public Statement {
  public:
-  Assign(SourceLocation loc, Ptr<const Expression> lhs,
-         Ptr<const Expression> rhs)
+  Assign(SourceLocation loc, Nonnull<const Expression*> lhs,
+         Nonnull<const Expression*> rhs)
       : Statement(Kind::Assign, loc), lhs(lhs), rhs(rhs) {}
 
   static auto classof(const Statement* stmt) -> bool {
     return stmt->Tag() == Kind::Assign;
   }
 
-  auto Lhs() const -> Ptr<const Expression> { return lhs; }
-  auto Rhs() const -> Ptr<const Expression> { return rhs; }
+  auto Lhs() const -> Nonnull<const Expression*> { return lhs; }
+  auto Rhs() const -> Nonnull<const Expression*> { return rhs; }
 
  private:
-  Ptr<const Expression> lhs;
-  Ptr<const Expression> rhs;
+  Nonnull<const Expression*> lhs;
+  Nonnull<const Expression*> rhs;
 };
 
 class VariableDefinition : public Statement {
  public:
-  VariableDefinition(SourceLocation loc, Ptr<const Pattern> pat,
-                     Ptr<const Expression> init)
+  VariableDefinition(SourceLocation loc, Nonnull<const Pattern*> pat,
+                     Nonnull<const Expression*> init)
       : Statement(Kind::VariableDefinition, loc), pat(pat), init(init) {}
 
   static auto classof(const Statement* stmt) -> bool {
     return stmt->Tag() == Kind::VariableDefinition;
   }
 
-  auto Pat() const -> Ptr<const Pattern> { return pat; }
-  auto Init() const -> Ptr<const Expression> { return init; }
+  auto Pat() const -> Nonnull<const Pattern*> { return pat; }
+  auto Init() const -> Nonnull<const Expression*> { return init; }
 
  private:
-  Ptr<const Pattern> pat;
-  Ptr<const Expression> init;
+  Nonnull<const Pattern*> pat;
+  Nonnull<const Expression*> init;
 };
 
 class If : public Statement {
  public:
-  If(SourceLocation loc, Ptr<const Expression> cond,
-     Ptr<const Statement> then_stmt,
-     std::optional<Ptr<const Statement>> else_stmt)
+  If(SourceLocation loc, Nonnull<const Expression*> cond,
+     Nonnull<const Statement*> then_stmt,
+     std::optional<Nonnull<const Statement*>> else_stmt)
       : Statement(Kind::If, loc),
         cond(cond),
         then_stmt(then_stmt),
@@ -121,23 +121,24 @@ class If : public Statement {
     return stmt->Tag() == Kind::If;
   }
 
-  auto Cond() const -> Ptr<const Expression> { return cond; }
-  auto ThenStmt() const -> Ptr<const Statement> { return then_stmt; }
-  auto ElseStmt() const -> std::optional<Ptr<const Statement>> {
+  auto Cond() const -> Nonnull<const Expression*> { return cond; }
+  auto ThenStmt() const -> Nonnull<const Statement*> { return then_stmt; }
+  auto ElseStmt() const -> std::optional<Nonnull<const Statement*>> {
     return else_stmt;
   }
 
  private:
-  Ptr<const Expression> cond;
-  Ptr<const Statement> then_stmt;
-  std::optional<Ptr<const Statement>> else_stmt;
+  Nonnull<const Expression*> cond;
+  Nonnull<const Statement*> then_stmt;
+  std::optional<Nonnull<const Statement*>> else_stmt;
 };
 
 class Return : public Statement {
  public:
-  Return(Ptr<Arena> arena, SourceLocation loc)
+  Return(Nonnull<Arena*> arena, SourceLocation loc)
       : Return(loc, arena->New<TupleLiteral>(loc), true) {}
-  Return(SourceLocation loc, Ptr<const Expression> exp, bool is_omitted_exp)
+  Return(SourceLocation loc, Nonnull<const Expression*> exp,
+         bool is_omitted_exp)
       : Statement(Kind::Return, loc),
         exp(exp),
         is_omitted_exp(is_omitted_exp) {}
@@ -146,63 +147,63 @@ class Return : public Statement {
     return stmt->Tag() == Kind::Return;
   }
 
-  auto Exp() const -> Ptr<const Expression> { return exp; }
+  auto Exp() const -> Nonnull<const Expression*> { return exp; }
   auto IsOmittedExp() const -> bool { return is_omitted_exp; }
 
  private:
-  Ptr<const Expression> exp;
+  Nonnull<const Expression*> exp;
   bool is_omitted_exp;
 };
 
 class Sequence : public Statement {
  public:
-  Sequence(SourceLocation loc, Ptr<const Statement> stmt,
-           std::optional<Ptr<const Statement>> next)
+  Sequence(SourceLocation loc, Nonnull<const Statement*> stmt,
+           std::optional<Nonnull<const Statement*>> next)
       : Statement(Kind::Sequence, loc), stmt(stmt), next(next) {}
 
   static auto classof(const Statement* stmt) -> bool {
     return stmt->Tag() == Kind::Sequence;
   }
 
-  auto Stmt() const -> Ptr<const Statement> { return stmt; }
-  auto Next() const -> std::optional<Ptr<const Statement>> { return next; }
+  auto Stmt() const -> Nonnull<const Statement*> { return stmt; }
+  auto Next() const -> std::optional<Nonnull<const Statement*>> { return next; }
 
  private:
-  Ptr<const Statement> stmt;
-  std::optional<Ptr<const Statement>> next;
+  Nonnull<const Statement*> stmt;
+  std::optional<Nonnull<const Statement*>> next;
 };
 
 class Block : public Statement {
  public:
-  Block(SourceLocation loc, std::optional<Ptr<const Statement>> stmt)
+  Block(SourceLocation loc, std::optional<Nonnull<const Statement*>> stmt)
       : Statement(Kind::Block, loc), stmt(stmt) {}
 
   static auto classof(const Statement* stmt) -> bool {
     return stmt->Tag() == Kind::Block;
   }
 
-  auto Stmt() const -> std::optional<Ptr<const Statement>> { return stmt; }
+  auto Stmt() const -> std::optional<Nonnull<const Statement*>> { return stmt; }
 
  private:
-  std::optional<Ptr<const Statement>> stmt;
+  std::optional<Nonnull<const Statement*>> stmt;
 };
 
 class While : public Statement {
  public:
-  While(SourceLocation loc, Ptr<const Expression> cond,
-        Ptr<const Statement> body)
+  While(SourceLocation loc, Nonnull<const Expression*> cond,
+        Nonnull<const Statement*> body)
       : Statement(Kind::While, loc), cond(cond), body(body) {}
 
   static auto classof(const Statement* stmt) -> bool {
     return stmt->Tag() == Kind::While;
   }
 
-  auto Cond() const -> Ptr<const Expression> { return cond; }
-  auto Body() const -> Ptr<const Statement> { return body; }
+  auto Cond() const -> Nonnull<const Expression*> { return cond; }
+  auto Body() const -> Nonnull<const Statement*> { return body; }
 
  private:
-  Ptr<const Expression> cond;
-  Ptr<const Statement> body;
+  Nonnull<const Expression*> cond;
+  Nonnull<const Statement*> body;
 };
 
 class Break : public Statement {
@@ -226,23 +227,25 @@ class Continue : public Statement {
 class Match : public Statement {
  public:
   Match(
-      SourceLocation loc, Ptr<const Expression> exp,
-      std::vector<std::pair<Ptr<const Pattern>, Ptr<const Statement>>> clauses)
+      SourceLocation loc, Nonnull<const Expression*> exp,
+      std::vector<std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>>>
+          clauses)
       : Statement(Kind::Match, loc), exp(exp), clauses(std::move(clauses)) {}
 
   static auto classof(const Statement* stmt) -> bool {
     return stmt->Tag() == Kind::Match;
   }
 
-  auto Exp() const -> Ptr<const Expression> { return exp; }
-  auto Clauses() const -> const
-      std::vector<std::pair<Ptr<const Pattern>, Ptr<const Statement>>>& {
+  auto Exp() const -> Nonnull<const Expression*> { return exp; }
+  auto Clauses() const -> const std::vector<
+      std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>>>& {
     return clauses;
   }
 
  private:
-  Ptr<const Expression> exp;
-  std::vector<std::pair<Ptr<const Pattern>, Ptr<const Statement>>> clauses;
+  Nonnull<const Expression*> exp;
+  std::vector<std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>>>
+      clauses;
 };
 
 // A continuation statement.
@@ -253,7 +256,7 @@ class Match : public Statement {
 class Continuation : public Statement {
  public:
   Continuation(SourceLocation loc, std::string continuation_variable,
-               Ptr<const Statement> body)
+               Nonnull<const Statement*> body)
       : Statement(Kind::Continuation, loc),
         continuation_variable(std::move(continuation_variable)),
         body(body) {}
@@ -265,11 +268,11 @@ class Continuation : public Statement {
   auto ContinuationVariable() const -> const std::string& {
     return continuation_variable;
   }
-  auto Body() const -> Ptr<const Statement> { return body; }
+  auto Body() const -> Nonnull<const Statement*> { return body; }
 
  private:
   std::string continuation_variable;
-  Ptr<const Statement> body;
+  Nonnull<const Statement*> body;
 };
 
 // A run statement.
@@ -277,17 +280,17 @@ class Continuation : public Statement {
 //     __run <argument>;
 class Run : public Statement {
  public:
-  Run(SourceLocation loc, Ptr<const Expression> argument)
+  Run(SourceLocation loc, Nonnull<const Expression*> argument)
       : Statement(Kind::Run, loc), argument(argument) {}
 
   static auto classof(const Statement* stmt) -> bool {
     return stmt->Tag() == Kind::Run;
   }
 
-  auto Argument() const -> Ptr<const Expression> { return argument; }
+  auto Argument() const -> Nonnull<const Expression*> { return argument; }
 
  private:
-  Ptr<const Expression> argument;
+  Nonnull<const Expression*> argument;
 };
 
 // An await statement.

+ 3 - 3
executable_semantics/common/arena.h

@@ -16,10 +16,10 @@ class Arena {
  public:
   // Allocates an object in the arena, returning a pointer to it.
   template <typename T, typename... Args>
-  auto New(Args&&... args) -> Ptr<T> {
+  auto New(Args&&... args) -> Nonnull<T*> {
     auto smart_ptr =
         std::make_unique<ArenaEntryTyped<T>>(std::forward<Args>(args)...);
-    Ptr<T> ptr = smart_ptr->Instance();
+    Nonnull<T*> ptr = smart_ptr->Instance();
     arena.push_back(std::move(smart_ptr));
     return ptr;
   }
@@ -40,7 +40,7 @@ class Arena {
     explicit ArenaEntryTyped(Args&&... args)
         : instance(std::forward<Args>(args)...) {}
 
-    auto Instance() -> Ptr<T> { return Ptr<T>(&instance); }
+    auto Instance() -> Nonnull<T*> { return Nonnull<T*>(&instance); }
 
    private:
     T instance;

+ 10 - 3
executable_semantics/common/ptr.h

@@ -5,11 +5,18 @@
 #ifndef EXECUTABLE_SEMANTICS_COMMON_PTR_H_
 #define EXECUTABLE_SEMANTICS_COMMON_PTR_H_
 
+#include <type_traits>
+
 namespace Carbon {
 
-// A non-nullable pointer. Written as `Ptr<T>` instead of `T*`.
-template <typename T>
-using Ptr = T* _Nonnull __attribute__((nonnull));
+// A non-nullable pointer. Written as `Nonnull<T*>` instead of `T*`.
+//
+// Note LLVM primarily enforces the attribute on function calls that can be
+// proven to be called with nullptr; in other places, this is essentially a
+// comment.
+template <typename T,
+          typename std::enable_if_t<std::is_pointer_v<T>>* = nullptr>
+using Nonnull = T _Nonnull __attribute__((nonnull));
 
 }  // namespace Carbon
 

+ 2 - 1
executable_semantics/interpreter/action.cpp

@@ -47,7 +47,8 @@ void Action::Print(llvm::raw_ostream& out) const {
   }
 }
 
-void Action::PrintList(const Stack<Ptr<Action>>& ls, llvm::raw_ostream& out) {
+void Action::PrintList(const Stack<Nonnull<Action*>>& ls,
+                       llvm::raw_ostream& out) {
   llvm::ListSeparator sep(" :: ");
   for (const auto& action : ls) {
     out << sep << *action;

+ 17 - 16
executable_semantics/interpreter/action.h

@@ -38,13 +38,13 @@ class Action {
   auto Pos() const -> int { return pos; }
 
   // Results from a subexpression.
-  auto Results() const -> const std::vector<Ptr<const Value>>& {
+  auto Results() const -> const std::vector<Nonnull<const Value*>>& {
     return results;
   }
 
   void SetPos(int pos) { this->pos = pos; }
 
-  void AddResult(Ptr<const Value> result) { results.push_back(result); }
+  void AddResult(Nonnull<const Value*> result) { results.push_back(result); }
 
   void Clear() {
     pos = 0;
@@ -55,7 +55,8 @@ class Action {
   // object.
   auto Tag() const -> Kind { return tag; }
 
-  static void PrintList(const Stack<Ptr<Action>>& ls, llvm::raw_ostream& out);
+  static void PrintList(const Stack<Nonnull<Action*>>& ls,
+                        llvm::raw_ostream& out);
 
   void Print(llvm::raw_ostream& out) const;
   LLVM_DUMP_METHOD void Dump() const { Print(llvm::errs()); }
@@ -67,69 +68,69 @@ class Action {
 
  private:
   int pos = 0;
-  std::vector<Ptr<const Value>> results;
+  std::vector<Nonnull<const Value*>> results;
 
   const Kind tag;
 };
 
 class LValAction : public Action {
  public:
-  explicit LValAction(Ptr<const Expression> exp)
+  explicit LValAction(Nonnull<const Expression*> exp)
       : Action(Kind::LValAction), exp(exp) {}
 
   static auto classof(const Action* action) -> bool {
     return action->Tag() == Kind::LValAction;
   }
 
-  auto Exp() const -> Ptr<const Expression> { return exp; }
+  auto Exp() const -> Nonnull<const Expression*> { return exp; }
 
  private:
-  Ptr<const Expression> exp;
+  Nonnull<const Expression*> exp;
 };
 
 class ExpressionAction : public Action {
  public:
-  explicit ExpressionAction(Ptr<const Expression> exp)
+  explicit ExpressionAction(Nonnull<const Expression*> exp)
       : Action(Kind::ExpressionAction), exp(exp) {}
 
   static auto classof(const Action* action) -> bool {
     return action->Tag() == Kind::ExpressionAction;
   }
 
-  auto Exp() const -> Ptr<const Expression> { return exp; }
+  auto Exp() const -> Nonnull<const Expression*> { return exp; }
 
  private:
-  Ptr<const Expression> exp;
+  Nonnull<const Expression*> exp;
 };
 
 class PatternAction : public Action {
  public:
-  explicit PatternAction(Ptr<const Pattern> pat)
+  explicit PatternAction(Nonnull<const Pattern*> pat)
       : Action(Kind::PatternAction), pat(pat) {}
 
   static auto classof(const Action* action) -> bool {
     return action->Tag() == Kind::PatternAction;
   }
 
-  auto Pat() const -> Ptr<const Pattern> { return pat; }
+  auto Pat() const -> Nonnull<const Pattern*> { return pat; }
 
  private:
-  Ptr<const Pattern> pat;
+  Nonnull<const Pattern*> pat;
 };
 
 class StatementAction : public Action {
  public:
-  explicit StatementAction(Ptr<const Statement> stmt)
+  explicit StatementAction(Nonnull<const Statement*> stmt)
       : Action(Kind::StatementAction), stmt(stmt) {}
 
   static auto classof(const Action* action) -> bool {
     return action->Tag() == Kind::StatementAction;
   }
 
-  auto Stmt() const -> Ptr<const Statement> { return stmt; }
+  auto Stmt() const -> Nonnull<const Statement*> { return stmt; }
 
  private:
-  Ptr<const Statement> stmt;
+  Nonnull<const Statement*> stmt;
 };
 
 }  // namespace Carbon

+ 7 - 7
executable_semantics/interpreter/dictionary.h

@@ -20,10 +20,10 @@ class Dictionary {
   struct Node {
     using ValueType = std::pair<K, V>;
 
-    Node(ValueType e, std::optional<Ptr<Node>> n) : curr(e), next(n) {}
+    Node(ValueType e, std::optional<Nonnull<Node*>> n) : curr(e), next(n) {}
 
     const ValueType curr;
-    const std::optional<Ptr<Node>> next;
+    const std::optional<Nonnull<Node*>> next;
 
     // Node cells are part of a "persistent data structure" and are thus
     // immutable.
@@ -39,7 +39,7 @@ class Dictionary {
     using reference = const value_type&;
     using iterator_category = std::forward_iterator_tag;
 
-    Iterator(std::optional<Ptr<Node>> x) : p(x) {}
+    Iterator(std::optional<Nonnull<Node*>> x) : p(x) {}
     Iterator(const Iterator& iter) : p(iter.p) {}
     Iterator& operator++() {
       p = (*p)->next;
@@ -56,11 +56,11 @@ class Dictionary {
     const value_type* operator->() { return &(*p)->curr; }
 
    private:
-    std::optional<Ptr<Node>> p;
+    std::optional<Nonnull<Node*>> p;
   };
 
   // Create an empty dictionary.
-  explicit Dictionary(Ptr<Arena> arena) : arena(arena) {}
+  explicit Dictionary(Nonnull<Arena*> arena) : arena(arena) {}
 
   // Return the value associated with the given key.
   // Time complexity: O(n) where n is the number of times
@@ -90,8 +90,8 @@ class Dictionary {
   auto end() const -> Iterator { return Iterator(std::nullopt); }
 
  private:
-  std::optional<Ptr<Node>> head;
-  Ptr<Arena> arena;
+  std::optional<Nonnull<Node*>> head;
+  Nonnull<Arena*> arena;
 };
 
 }  // namespace Carbon

+ 5 - 4
executable_semantics/interpreter/exec_program.cpp

@@ -15,8 +15,9 @@ namespace Carbon {
 
 // Adds builtins, currently only Print(). Note Print() is experimental, not
 // standardized, but is made available for printing state in tests.
-static void AddIntrinsics(Ptr<Arena> arena,
-                          std::vector<Ptr<const Declaration>>* declarations) {
+static void AddIntrinsics(
+    Nonnull<Arena*> arena,
+    std::vector<Nonnull<const Declaration*>>* declarations) {
   SourceLocation loc("<intrinsic>", 0);
   std::vector<TuplePattern::Field> print_fields = {TuplePattern::Field(
       "0",
@@ -36,7 +37,7 @@ static void AddIntrinsics(Ptr<Arena> arena,
   declarations->insert(declarations->begin(), print);
 }
 
-void ExecProgram(Ptr<Arena> arena, AST ast) {
+void ExecProgram(Nonnull<Arena*> arena, AST ast) {
   AddIntrinsics(arena, &ast.declarations);
   if (tracing_output) {
     llvm::outs() << "********** source program **********\n";
@@ -49,7 +50,7 @@ void ExecProgram(Ptr<Arena> arena, AST ast) {
   TypeChecker::TypeCheckContext p = type_checker.TopLevel(ast.declarations);
   TypeEnv top = p.types;
   Env ct_top = p.values;
-  std::vector<Ptr<const Declaration>> new_decls;
+  std::vector<Nonnull<const Declaration*>> new_decls;
   for (const auto decl : ast.declarations) {
     new_decls.push_back(type_checker.MakeTypeChecked(decl, top, ct_top));
   }

+ 1 - 1
executable_semantics/interpreter/exec_program.h

@@ -14,7 +14,7 @@
 namespace Carbon {
 
 // Runs the top-level declaration list.
-void ExecProgram(Ptr<Arena> arena, AST ast);
+void ExecProgram(Nonnull<Arena*> arena, AST ast);
 
 }  // namespace Carbon
 

+ 3 - 3
executable_semantics/interpreter/frame.h

@@ -33,7 +33,7 @@ struct Frame {
   Frame(const Frame&) = delete;
   Frame& operator=(const Frame&) = delete;
 
-  Frame(std::string n, Stack<Ptr<Scope>> s, Stack<Ptr<Action>> c)
+  Frame(std::string n, Stack<Nonnull<Scope*>> s, Stack<Nonnull<Action*>> c)
       : name(std::move(std::move(n))), scopes(s), todo(c), continuation() {}
 
   void Print(llvm::raw_ostream& out) const;
@@ -47,11 +47,11 @@ struct Frame {
   // blocks within the function. The scope at the top of the stack is
   // the current scope and its environment is the one used for looking
   // up the value associated with a variable.
-  Stack<Ptr<Scope>> scopes;
+  Stack<Nonnull<Scope*>> scopes;
   // The actions that need to be executed in the future of the
   // current function call. The top of the stack is the action
   // that is executed first.
-  Stack<Ptr<Action>> todo;
+  Stack<Nonnull<Action*>> todo;
   // If this frame is the bottom frame of a continuation, then it stores
   // the address of the continuation.
   std::optional<Address> continuation;

+ 4 - 3
executable_semantics/interpreter/heap.cpp

@@ -9,7 +9,7 @@
 
 namespace Carbon {
 
-auto Heap::AllocateValue(Ptr<const Value> v) -> Address {
+auto Heap::AllocateValue(Nonnull<const Value*> v) -> Address {
   // Putting the following two side effects together in this function
   // ensures that we don't do anything else in between, which is really bad!
   // Consider whether to include a copy of the input v in this function
@@ -20,12 +20,13 @@ auto Heap::AllocateValue(Ptr<const Value> v) -> Address {
   return a;
 }
 
-auto Heap::Read(const Address& a, SourceLocation loc) -> Ptr<const Value> {
+auto Heap::Read(const Address& a, SourceLocation loc) -> Nonnull<const Value*> {
   this->CheckAlive(a, loc);
   return values[a.index]->GetField(arena, a.field_path, loc);
 }
 
-void Heap::Write(const Address& a, Ptr<const Value> v, SourceLocation loc) {
+void Heap::Write(const Address& a, Nonnull<const Value*> v,
+                 SourceLocation loc) {
   this->CheckAlive(a, loc);
   values[a.index] = values[a.index]->SetField(arena, a.field_path, v, loc);
 }

+ 6 - 6
executable_semantics/interpreter/heap.h

@@ -18,21 +18,21 @@ namespace Carbon {
 class Heap {
  public:
   // Constructs an empty Heap.
-  explicit Heap(Ptr<Arena> arena) : arena(arena){};
+  explicit Heap(Nonnull<Arena*> arena) : arena(arena){};
 
   Heap(const Heap&) = delete;
   Heap& operator=(const Heap&) = delete;
 
   // Returns the value at the given address in the heap after
   // checking that it is alive.
-  auto Read(const Address& a, SourceLocation loc) -> Ptr<const Value>;
+  auto Read(const Address& a, SourceLocation loc) -> Nonnull<const Value*>;
 
   // Writes the given value at the address in the heap after
   // checking that the address is alive.
-  void Write(const Address& a, Ptr<const Value> v, SourceLocation loc);
+  void Write(const Address& a, Nonnull<const Value*> v, SourceLocation loc);
 
   // Put the given value on the heap and mark it as alive.
-  auto AllocateValue(Ptr<const Value> v) -> Address;
+  auto AllocateValue(Nonnull<const Value*> v) -> Address;
 
   // Marks the object at this address, and all of its sub-objects, as dead.
   void Deallocate(const Address& address);
@@ -49,8 +49,8 @@ class Heap {
   // Signal an error if the address is no longer alive.
   void CheckAlive(const Address& address, SourceLocation loc);
 
-  Ptr<Arena> arena;
-  std::vector<Ptr<const Value>> values;
+  Nonnull<Arena*> arena;
+  std::vector<Nonnull<const Value*>> values;
   std::vector<bool> alive;
 };
 

+ 80 - 75
executable_semantics/interpreter/interpreter.cpp

@@ -46,7 +46,7 @@ void Interpreter::PrintEnv(Env values, llvm::raw_ostream& out) {
 //
 
 auto Interpreter::CurrentEnv() -> Env {
-  Ptr<Frame> frame = stack.Top();
+  Nonnull<Frame*> frame = stack.Top();
   return frame->scopes.Top()->values;
 }
 
@@ -75,8 +75,8 @@ void Interpreter::PrintState(llvm::raw_ostream& out) {
 }
 
 auto Interpreter::EvalPrim(Operator op,
-                           const std::vector<Ptr<const Value>>& args,
-                           SourceLocation loc) -> Ptr<const Value> {
+                           const std::vector<Nonnull<const Value*>>& args,
+                           SourceLocation loc) -> Nonnull<const Value*> {
   switch (op) {
     case Operator::Neg:
       return arena->New<IntValue>(-cast<IntValue>(*args[0]).Val());
@@ -128,11 +128,12 @@ void Interpreter::InitEnv(const Declaration& d, Env* env) {
       const ClassDefinition& class_def = cast<ClassDeclaration>(d).Definition();
       VarValues fields;
       VarValues methods;
-      for (Ptr<const Member> m : class_def.members) {
+      for (Nonnull<const Member*> m : class_def.members) {
         switch (m->Tag()) {
           case Member::Kind::FieldMember: {
-            Ptr<const BindingPattern> binding = cast<FieldMember>(*m).Binding();
-            Ptr<const Expression> type_expression =
+            Nonnull<const BindingPattern*> binding =
+                cast<FieldMember>(*m).Binding();
+            Nonnull<const Expression*> type_expression =
                 cast<ExpressionPattern>(*binding->Type()).Expression();
             auto type = InterpExp(Env(arena), type_expression);
             fields.push_back(make_pair(*binding->Name(), type));
@@ -172,13 +173,14 @@ void Interpreter::InitEnv(const Declaration& d, Env* env) {
   }
 }
 
-void Interpreter::InitGlobals(const std::vector<Ptr<const Declaration>>& fs) {
+void Interpreter::InitGlobals(
+    const std::vector<Nonnull<const Declaration*>>& fs) {
   for (const auto d : fs) {
     InitEnv(*d, &globals);
   }
 }
 
-void Interpreter::DeallocateScope(Ptr<Scope> scope) {
+void Interpreter::DeallocateScope(Nonnull<Scope*> scope) {
   for (const auto& l : scope->locals) {
     std::optional<Address> a = scope->values.Get(l);
     CHECK(a);
@@ -186,15 +188,16 @@ void Interpreter::DeallocateScope(Ptr<Scope> scope) {
   }
 }
 
-void Interpreter::DeallocateLocals(Ptr<Frame> frame) {
+void Interpreter::DeallocateLocals(Nonnull<Frame*> frame) {
   while (!frame->scopes.IsEmpty()) {
     DeallocateScope(frame->scopes.Top());
     frame->scopes.Pop();
   }
 }
 
-auto Interpreter::CreateTuple(Ptr<Action> act, Ptr<const Expression> exp)
-    -> Ptr<const Value> {
+auto Interpreter::CreateTuple(Nonnull<Action*> act,
+                              Nonnull<const Expression*> exp)
+    -> Nonnull<const Value*> {
   //    { { (v1,...,vn) :: C, E, F} :: S, H}
   // -> { { `(v1,...,vn) :: C, E, F} :: S, H}
   const auto& tup_lit = cast<TupleLiteral>(*exp);
@@ -208,7 +211,7 @@ auto Interpreter::CreateTuple(Ptr<Action> act, Ptr<const Expression> exp)
   return arena->New<TupleValue>(std::move(elements));
 }
 
-auto Interpreter::PatternMatch(Ptr<const Value> p, Ptr<const Value> v,
+auto Interpreter::PatternMatch(Nonnull<const Value*> p, Nonnull<const Value*> v,
                                SourceLocation loc) -> std::optional<Env> {
   switch (p->Tag()) {
     case Value::Kind::BindingPlaceholderValue: {
@@ -303,7 +306,8 @@ auto Interpreter::PatternMatch(Ptr<const Value> p, Ptr<const Value> v,
   }
 }
 
-void Interpreter::PatternAssignment(Ptr<const Value> pat, Ptr<const Value> val,
+void Interpreter::PatternAssignment(Nonnull<const Value*> pat,
+                                    Nonnull<const Value*> val,
                                     SourceLocation loc) {
   switch (pat->Tag()) {
     case Value::Kind::PointerValue:
@@ -320,7 +324,7 @@ void Interpreter::PatternAssignment(Ptr<const Value> pat, Ptr<const Value> val,
                 << pat_tup << "\n  value: " << val_tup;
           }
           for (const TupleElement& pattern_element : pat_tup.Elements()) {
-            std::optional<Ptr<const Value>> value_field =
+            std::optional<Nonnull<const Value*>> value_field =
                 val_tup.FindField(pattern_element.name);
             if (!value_field) {
               FATAL_RUNTIME_ERROR(loc)
@@ -358,8 +362,8 @@ void Interpreter::PatternAssignment(Ptr<const Value> pat, Ptr<const Value> val,
 }
 
 auto Interpreter::StepLvalue() -> Transition {
-  Ptr<Action> act = stack.Top()->todo.Top();
-  Ptr<const Expression> exp = cast<LValAction>(*act).Exp();
+  Nonnull<Action*> act = stack.Top()->todo.Top();
+  Nonnull<const Expression*> exp = cast<LValAction>(*act).Exp();
   if (tracing_output) {
     llvm::outs() << "--- step lvalue " << *exp << " (" << exp->SourceLoc()
                  << ") --->\n";
@@ -370,7 +374,7 @@ auto Interpreter::StepLvalue() -> Transition {
       // -> { {E(x) :: C, E, F} :: S, H}
       Address pointer =
           GetFromEnv(exp->SourceLoc(), cast<IdentifierExpression>(*exp).Name());
-      Ptr<const Value> v = arena->New<PointerValue>(pointer);
+      Nonnull<const Value*> v = arena->New<PointerValue>(pointer);
       return Done{v};
     }
     case Expression::Kind::FieldAccessExpression: {
@@ -412,7 +416,7 @@ auto Interpreter::StepLvalue() -> Transition {
       if (act->Pos() == 0) {
         //    { {(f1=e1,...) :: C, E, F} :: S, H}
         // -> { {e1 :: (f1=[],...) :: C, E, F} :: S, H}
-        Ptr<const Expression> e1 =
+        Nonnull<const Expression*> e1 =
             cast<TupleLiteral>(*exp).Fields()[0].expression;
         return Spawn{arena->New<LValAction>(e1)};
       } else if (act->Pos() !=
@@ -421,7 +425,7 @@ auto Interpreter::StepLvalue() -> Transition {
         //    H}
         // -> { { ek+1 :: (f1=v1,..., fk=vk, fk+1=[],...) :: C, E, F} :: S,
         // H}
-        Ptr<const Expression> elt =
+        Nonnull<const Expression*> elt =
             cast<TupleLiteral>(*exp).Fields()[act->Pos()].expression;
         return Spawn{arena->New<LValAction>(elt)};
       } else {
@@ -446,8 +450,8 @@ auto Interpreter::StepLvalue() -> Transition {
 }
 
 auto Interpreter::StepExp() -> Transition {
-  Ptr<Action> act = stack.Top()->todo.Top();
-  Ptr<const Expression> exp = cast<ExpressionAction>(*act).Exp();
+  Nonnull<Action*> act = stack.Top()->todo.Top();
+  Nonnull<const Expression*> exp = cast<ExpressionAction>(*act).Exp();
   if (tracing_output) {
     llvm::outs() << "--- step exp " << *exp << " (" << exp->SourceLoc()
                  << ") --->\n";
@@ -472,7 +476,7 @@ auto Interpreter::StepExp() -> Transition {
         }
         std::string f =
             std::to_string(cast<IntValue>(*act->Results()[1]).Val());
-        std::optional<Ptr<const Value>> field = tuple->FindField(f);
+        std::optional<Nonnull<const Value*>> field = tuple->FindField(f);
         if (!field) {
           FATAL_RUNTIME_ERROR_NO_LINE()
               << "field " << f << " not in " << *tuple;
@@ -485,7 +489,7 @@ auto Interpreter::StepExp() -> Transition {
         if (cast<TupleLiteral>(*exp).Fields().size() > 0) {
           //    { {(f1=e1,...) :: C, E, F} :: S, H}
           // -> { {e1 :: (f1=[],...) :: C, E, F} :: S, H}
-          Ptr<const Expression> e1 =
+          Nonnull<const Expression*> e1 =
               cast<TupleLiteral>(*exp).Fields()[0].expression;
           return Spawn{arena->New<ExpressionAction>(e1)};
         } else {
@@ -497,7 +501,7 @@ auto Interpreter::StepExp() -> Transition {
         //    H}
         // -> { { ek+1 :: (f1=v1,..., fk=vk, fk+1=[],...) :: C, E, F} :: S,
         // H}
-        Ptr<const Expression> elt =
+        Nonnull<const Expression*> elt =
             cast<TupleLiteral>(*exp).Fields()[act->Pos()].expression;
         return Spawn{arena->New<ExpressionAction>(elt)};
       } else {
@@ -537,7 +541,7 @@ auto Interpreter::StepExp() -> Transition {
       if (act->Pos() != static_cast<int>(op.Arguments().size())) {
         //    { {v :: op(vs,[],e,es) :: C, E, F} :: S, H}
         // -> { {e :: op(vs,v,[],es) :: C, E, F} :: S, H}
-        Ptr<const Expression> arg = op.Arguments()[act->Pos()];
+        Nonnull<const Expression*> arg = op.Arguments()[act->Pos()];
         return Spawn{arena->New<ExpressionAction>(arg)};
       } else {
         //    { {v :: op(vs,[]) :: C, E, F} :: S, H}
@@ -561,14 +565,14 @@ auto Interpreter::StepExp() -> Transition {
         // -> { {C',E',F'} :: {C, E, F} :: S, H}
         switch (act->Results()[0]->Tag()) {
           case Value::Kind::ClassType: {
-            Ptr<const Value> arg =
+            Nonnull<const Value*> arg =
                 CopyVal(arena, act->Results()[1], exp->SourceLoc());
             return Done{arena->New<StructValue>(act->Results()[0], arg)};
           }
           case Value::Kind::AlternativeConstructorValue: {
             const auto& alt =
                 cast<AlternativeConstructorValue>(*act->Results()[0]);
-            Ptr<const Value> arg =
+            Nonnull<const Value*> arg =
                 CopyVal(arena, act->Results()[1], exp->SourceLoc());
             return Done{arena->New<AlternativeValue>(alt.AltName(),
                                                      alt.ChoiceName(), arg)};
@@ -577,7 +581,7 @@ auto Interpreter::StepExp() -> Transition {
             return CallFunction{
                 // TODO: Think about a cleaner way to cast between Ptr types.
                 // (multiple TODOs)
-                .function = Ptr<const FunctionValue>(
+                .function = Nonnull<const FunctionValue*>(
                     cast<FunctionValue>(act->Results()[0])),
                 .args = act->Results()[1],
                 .loc = exp->SourceLoc()};
@@ -594,7 +598,7 @@ auto Interpreter::StepExp() -> Transition {
       switch (cast<IntrinsicExpression>(*exp).Intrinsic()) {
         case IntrinsicExpression::IntrinsicKind::Print:
           Address pointer = GetFromEnv(exp->SourceLoc(), "format_str");
-          Ptr<const Value> pointee = heap.Read(pointer, exp->SourceLoc());
+          Nonnull<const Value*> pointee = heap.Read(pointer, exp->SourceLoc());
           CHECK(pointee->Tag() == Value::Kind::StringValue);
           // TODO: This could eventually use something like llvm::formatv.
           llvm::outs() << cast<StringValue>(*pointee).Val();
@@ -646,8 +650,8 @@ auto Interpreter::StepExp() -> Transition {
 }
 
 auto Interpreter::StepPattern() -> Transition {
-  Ptr<Action> act = stack.Top()->todo.Top();
-  Ptr<const Pattern> pattern = cast<PatternAction>(*act).Pat();
+  Nonnull<Action*> act = stack.Top()->todo.Top();
+  Nonnull<const Pattern*> pattern = cast<PatternAction>(*act).Pat();
   if (tracing_output) {
     llvm::outs() << "--- step pattern " << *pattern << " ("
                  << pattern->SourceLoc() << ") --->\n";
@@ -672,7 +676,7 @@ auto Interpreter::StepPattern() -> Transition {
         if (tuple.Fields().empty()) {
           return Done{TupleValue::Empty()};
         } else {
-          Ptr<const Pattern> p1 = tuple.Fields()[0].pattern;
+          Nonnull<const Pattern*> p1 = tuple.Fields()[0].pattern;
           return Spawn{(arena->New<PatternAction>(p1))};
         }
       } else if (act->Pos() != static_cast<int>(tuple.Fields().size())) {
@@ -680,7 +684,7 @@ auto Interpreter::StepPattern() -> Transition {
         //    H}
         // -> { { ek+1 :: (f1=v1,..., fk=vk, fk+1=[],...) :: C, E, F} :: S,
         // H}
-        Ptr<const Pattern> elt = tuple.Fields()[act->Pos()].pattern;
+        Nonnull<const Pattern*> elt = tuple.Fields()[act->Pos()].pattern;
         return Spawn{arena->New<PatternAction>(elt)};
       } else {
         std::vector<TupleElement> elements;
@@ -711,7 +715,7 @@ auto Interpreter::StepPattern() -> Transition {
   }
 }
 
-static auto IsWhileAct(Ptr<Action> act) -> bool {
+static auto IsWhileAct(Nonnull<Action*> act) -> bool {
   switch (act->Tag()) {
     case Action::Kind::StatementAction:
       switch (cast<StatementAction>(*act).Stmt()->Tag()) {
@@ -725,7 +729,7 @@ static auto IsWhileAct(Ptr<Action> act) -> bool {
   }
 }
 
-static auto HasLocalScope(Ptr<Action> act) -> bool {
+static auto HasLocalScope(Nonnull<Action*> act) -> bool {
   switch (act->Tag()) {
     case Action::Kind::StatementAction:
       switch (cast<StatementAction>(*act).Stmt()->Tag()) {
@@ -741,9 +745,9 @@ static auto HasLocalScope(Ptr<Action> act) -> bool {
 }
 
 auto Interpreter::StepStmt() -> Transition {
-  Ptr<Frame> frame = stack.Top();
-  Ptr<Action> act = frame->todo.Top();
-  Ptr<const Statement> stmt = cast<StatementAction>(*act).Stmt();
+  Nonnull<Frame*> frame = stack.Top();
+  Nonnull<Action*> act = frame->todo.Top();
+  Nonnull<const Statement*> stmt = cast<StatementAction>(*act).Stmt();
   if (tracing_output) {
     llvm::outs() << "--- step stmt ";
     stmt->PrintDepth(1, llvm::outs());
@@ -849,7 +853,7 @@ auto Interpreter::StepStmt() -> Transition {
           return Done{};
         }
       } else {
-        Ptr<Scope> scope = frame->scopes.Top();
+        Nonnull<Scope*> scope = frame->scopes.Top();
         DeallocateScope(scope);
         frame->scopes.Pop(1);
         return Done{};
@@ -867,8 +871,8 @@ auto Interpreter::StepStmt() -> Transition {
       } else {
         //    { { v :: (x = []) :: C, E, F} :: S, H}
         // -> { { C, E(x := a), F} :: S, H(a := copy(v))}
-        Ptr<const Value> v = act->Results()[0];
-        Ptr<const Value> p = act->Results()[1];
+        Nonnull<const Value*> v = act->Results()[0];
+        Nonnull<const Value*> p = act->Results()[1];
 
         std::optional<Env> matches = PatternMatch(p, v, stmt->SourceLoc());
         CHECK(matches)
@@ -934,7 +938,7 @@ auto Interpreter::StepStmt() -> Transition {
       } else {
         //    { {v :: return [] :: C, E, F} :: {C', E', F'} :: S, H}
         // -> { {v :: C', E', F'} :: S, H}
-        Ptr<const Value> ret_val =
+        Nonnull<const Value*> ret_val =
             CopyVal(arena, act->Results()[0], stmt->SourceLoc());
         return UnwindFunctionCall{ret_val};
       }
@@ -957,8 +961,8 @@ auto Interpreter::StepStmt() -> Transition {
       CHECK(act->Pos() == 0);
       // Create a continuation object by creating a frame similar the
       // way one is created in a function call.
-      auto scopes = Stack<Ptr<Scope>>(arena->New<Scope>(CurrentEnv()));
-      Stack<Ptr<Action>> todo;
+      auto scopes = Stack<Nonnull<Scope*>>(arena->New<Scope>(CurrentEnv()));
+      Stack<Nonnull<Action*>> todo;
       todo.Push(arena->New<StatementAction>(
           arena->New<Return>(arena, stmt->SourceLoc())));
       todo.Push(arena->New<StatementAction>(cast<Continuation>(*stmt).Body()));
@@ -966,7 +970,7 @@ auto Interpreter::StepStmt() -> Transition {
           arena->New<Frame>("__continuation", scopes, todo);
       Address continuation_address =
           heap.AllocateValue(arena->New<ContinuationValue>(
-              std::vector<Ptr<Frame>>({continuation_frame})));
+              std::vector<Nonnull<Frame*>>({continuation_frame})));
       // Store the continuation's address in the frame.
       continuation_frame->continuation = continuation_address;
       // Bind the continuation object to the continuation variable
@@ -991,7 +995,7 @@ auto Interpreter::StepStmt() -> Transition {
                 arena->New<TupleLiteral>(stmt->SourceLoc())));
         frame->todo.Push(ignore_result);
         // Push the continuation onto the current stack.
-        const std::vector<Ptr<Frame>>& continuation_vector =
+        const std::vector<Nonnull<Frame*>>& continuation_vector =
             cast<ContinuationValue>(*act->Results()[0]).Stack();
         for (auto frame_iter = continuation_vector.rbegin();
              frame_iter != continuation_vector.rend(); ++frame_iter) {
@@ -1003,7 +1007,7 @@ auto Interpreter::StepStmt() -> Transition {
       CHECK(act->Pos() == 0);
       // Pause the current continuation
       frame->todo.Pop();
-      std::vector<Ptr<Frame>> paused;
+      std::vector<Nonnull<Frame*>> paused;
       do {
         paused.push_back(stack.Pop());
       } while (paused.back()->continuation == std::nullopt);
@@ -1020,7 +1024,7 @@ class Interpreter::DoTransition {
   DoTransition(Interpreter* interpreter) : interpreter(interpreter) {}
 
   void operator()(const Done& done) {
-    Ptr<Frame> frame = interpreter->stack.Top();
+    Nonnull<Frame*> frame = interpreter->stack.Top();
     if (frame->todo.Top()->Tag() != Action::Kind::StatementAction) {
       CHECK(done.result);
       frame->todo.Pop();
@@ -1036,25 +1040,25 @@ class Interpreter::DoTransition {
   }
 
   void operator()(const Spawn& spawn) {
-    Ptr<Frame> frame = interpreter->stack.Top();
-    Ptr<Action> action = frame->todo.Top();
+    Nonnull<Frame*> frame = interpreter->stack.Top();
+    Nonnull<Action*> action = frame->todo.Top();
     action->SetPos(action->Pos() + 1);
     frame->todo.Push(spawn.child);
   }
 
   void operator()(const Delegate& delegate) {
-    Ptr<Frame> frame = interpreter->stack.Top();
+    Nonnull<Frame*> frame = interpreter->stack.Top();
     frame->todo.Pop();
     frame->todo.Push(delegate.delegate);
   }
 
   void operator()(const RunAgain&) {
-    Ptr<Action> action = interpreter->stack.Top()->todo.Top();
+    Nonnull<Action*> action = interpreter->stack.Top()->todo.Top();
     action->SetPos(action->Pos() + 1);
   }
 
   void operator()(const UnwindTo& unwind_to) {
-    Ptr<Frame> frame = interpreter->stack.Top();
+    Nonnull<Frame*> frame = interpreter->stack.Top();
     while (frame->todo.Top() != unwind_to.new_top) {
       if (HasLocalScope(frame->todo.Top())) {
         interpreter->DeallocateScope(frame->scopes.Top());
@@ -1088,9 +1092,9 @@ class Interpreter::DoTransition {
       params.push_back(name);
     }
     auto scopes =
-        Stack<Ptr<Scope>>(interpreter->arena->New<Scope>(values, params));
+        Stack<Nonnull<Scope*>>(interpreter->arena->New<Scope>(values, params));
     CHECK(call.function->Body()) << "Calling a function that's missing a body";
-    auto todo = Stack<Ptr<Action>>(
+    auto todo = Stack<Nonnull<Action*>>(
         interpreter->arena->New<StatementAction>(*call.function->Body()));
     auto frame =
         interpreter->arena->New<Frame>(call.function->Name(), scopes, todo);
@@ -1100,18 +1104,18 @@ class Interpreter::DoTransition {
   void operator()(const ManualTransition&) {}
 
  private:
-  Ptr<Interpreter> interpreter;
+  Nonnull<Interpreter*> interpreter;
 };
 
 // State transition.
 void Interpreter::Step() {
-  Ptr<Frame> frame = stack.Top();
+  Nonnull<Frame*> frame = stack.Top();
   if (frame->todo.IsEmpty()) {
     FATAL_RUNTIME_ERROR_NO_LINE()
         << "fell off end of function " << frame->name << " without `return`";
   }
 
-  Ptr<Action> act = frame->todo.Top();
+  Nonnull<Action*> act = frame->todo.Top();
   switch (act->Tag()) {
     case Action::Kind::LValAction:
       std::visit(DoTransition(this), StepLvalue());
@@ -1128,8 +1132,8 @@ void Interpreter::Step() {
   }  // switch
 }
 
-auto Interpreter::InterpProgram(const std::vector<Ptr<const Declaration>>& fs)
-    -> int {
+auto Interpreter::InterpProgram(
+    const std::vector<Nonnull<const Declaration*>>& fs) -> int {
   // Check that the interpreter is in a clean state.
   CHECK(globals.IsEmpty());
   CHECK(stack.IsEmpty());
@@ -1142,12 +1146,12 @@ auto Interpreter::InterpProgram(const std::vector<Ptr<const Declaration>>& fs)
 
   SourceLocation loc("<InterpProgram()>", 0);
 
-  Ptr<const Expression> arg = arena->New<TupleLiteral>(loc);
-  Ptr<const Expression> call_main = arena->New<CallExpression>(
+  Nonnull<const Expression*> arg = arena->New<TupleLiteral>(loc);
+  Nonnull<const Expression*> call_main = arena->New<CallExpression>(
       loc, arena->New<IdentifierExpression>(loc, "main"), arg);
-  auto todo = Stack<Ptr<Action>>(arena->New<ExpressionAction>(call_main));
-  auto scopes = Stack<Ptr<Scope>>(arena->New<Scope>(globals));
-  stack = Stack<Ptr<Frame>>(arena->New<Frame>("top", scopes, todo));
+  auto todo = Stack<Nonnull<Action*>>(arena->New<ExpressionAction>(call_main));
+  auto scopes = Stack<Nonnull<Scope*>>(arena->New<Scope>(globals));
+  stack = Stack<Nonnull<Frame*>>(arena->New<Frame>("top", scopes, todo));
 
   if (tracing_output) {
     llvm::outs() << "********** calling main function **********\n";
@@ -1163,14 +1167,14 @@ auto Interpreter::InterpProgram(const std::vector<Ptr<const Declaration>>& fs)
   return cast<IntValue>(**program_value).Val();
 }
 
-auto Interpreter::InterpExp(Env values, Ptr<const Expression> e)
-    -> Ptr<const Value> {
+auto Interpreter::InterpExp(Env values, Nonnull<const Expression*> e)
+    -> Nonnull<const Value*> {
   CHECK(program_value == std::nullopt);
   auto program_value_guard =
       llvm::make_scope_exit([&] { program_value = std::nullopt; });
-  auto todo = Stack<Ptr<Action>>(arena->New<ExpressionAction>(e));
-  auto scopes = Stack<Ptr<Scope>>(arena->New<Scope>(values));
-  stack = Stack<Ptr<Frame>>(arena->New<Frame>("InterpExp", scopes, todo));
+  auto todo = Stack<Nonnull<Action*>>(arena->New<ExpressionAction>(e));
+  auto scopes = Stack<Nonnull<Scope*>>(arena->New<Scope>(values));
+  stack = Stack<Nonnull<Frame*>>(arena->New<Frame>("InterpExp", scopes, todo));
 
   while (stack.Count() > 1 || !stack.Top()->todo.IsEmpty()) {
     Step();
@@ -1179,14 +1183,15 @@ auto Interpreter::InterpExp(Env values, Ptr<const Expression> e)
   return *program_value;
 }
 
-auto Interpreter::InterpPattern(Env values, Ptr<const Pattern> p)
-    -> Ptr<const Value> {
+auto Interpreter::InterpPattern(Env values, Nonnull<const Pattern*> p)
+    -> Nonnull<const Value*> {
   CHECK(program_value == std::nullopt);
   auto program_value_guard =
       llvm::make_scope_exit([&] { program_value = std::nullopt; });
-  auto todo = Stack<Ptr<Action>>(arena->New<PatternAction>(p));
-  auto scopes = Stack<Ptr<Scope>>(arena->New<Scope>(values));
-  stack = Stack<Ptr<Frame>>(arena->New<Frame>("InterpPattern", scopes, todo));
+  auto todo = Stack<Nonnull<Action*>>(arena->New<PatternAction>(p));
+  auto scopes = Stack<Nonnull<Scope*>>(arena->New<Scope>(values));
+  stack =
+      Stack<Nonnull<Frame*>>(arena->New<Frame>("InterpPattern", scopes, todo));
 
   while (stack.Count() > 1 || !stack.Top()->todo.IsEmpty()) {
     Step();

+ 27 - 25
executable_semantics/interpreter/interpreter.h

@@ -24,25 +24,27 @@ using Env = Dictionary<std::string, Address>;
 
 class Interpreter {
  public:
-  explicit Interpreter(Ptr<Arena> arena)
+  explicit Interpreter(Nonnull<Arena*> arena)
       : arena(arena), globals(arena), heap(arena) {}
 
   // Interpret the whole program.
-  auto InterpProgram(const std::vector<Ptr<const Declaration>>& fs) -> int;
+  auto InterpProgram(const std::vector<Nonnull<const Declaration*>>& fs) -> int;
 
   // Interpret an expression at compile-time.
-  auto InterpExp(Env values, Ptr<const Expression> e) -> Ptr<const Value>;
+  auto InterpExp(Env values, Nonnull<const Expression*> e)
+      -> Nonnull<const Value*>;
 
   // Interpret a pattern at compile-time.
-  auto InterpPattern(Env values, Ptr<const Pattern> p) -> Ptr<const Value>;
+  auto InterpPattern(Env values, Nonnull<const Pattern*> p)
+      -> Nonnull<const Value*>;
 
   // Attempts to match `v` against the pattern `p`. If matching succeeds,
   // returns the bindings of pattern variables to their matched values.
-  auto PatternMatch(Ptr<const Value> p, Ptr<const Value> v, SourceLocation loc)
-      -> std::optional<Env>;
+  auto PatternMatch(Nonnull<const Value*> p, Nonnull<const Value*> v,
+                    SourceLocation loc) -> std::optional<Env>;
 
   // Support TypeChecker allocating values on the heap.
-  auto AllocateValue(Ptr<const Value> v) -> Address {
+  auto AllocateValue(Nonnull<const Value*> v) -> Address {
     return heap.AllocateValue(v);
   }
 
@@ -62,19 +64,19 @@ class Interpreter {
   struct Done {
     // The value computed by the Action. Should always be nullopt for Statement
     // Actions, and never null for any other kind of Action.
-    std::optional<Ptr<const Value>> result;
+    std::optional<Nonnull<const Value*>> result;
   };
 
   // Transition type which spawns a new Action on the todo stack above the
   // current Action, and increments the current Action's position counter.
   struct Spawn {
-    Ptr<Action> child;
+    Nonnull<Action*> child;
   };
 
   // Transition type which spawns a new Action that replaces the current action
   // on the todo stack.
   struct Delegate {
-    Ptr<Action> delegate;
+    Nonnull<Action*> delegate;
   };
 
   // Transition type which keeps the current Action at the top of the stack,
@@ -84,21 +86,21 @@ class Interpreter {
   // Transition type which unwinds the `todo` and `scopes` stacks until it
   // reaches a specified Action lower in the stack.
   struct UnwindTo {
-    const Ptr<Action> new_top;
+    const Nonnull<Action*> new_top;
   };
 
   // Transition type which unwinds the entire current stack frame, and returns
   // a specified value to the caller.
   struct UnwindFunctionCall {
-    Ptr<const Value> return_val;
+    Nonnull<const Value*> return_val;
   };
 
   // Transition type which removes the current action from the top of the todo
   // stack, then creates a new stack frame which calls the specified function
   // with the specified arguments.
   struct CallFunction {
-    Ptr<const FunctionValue> function;
-    Ptr<const Value> args;
+    Nonnull<const FunctionValue*> function;
+    Nonnull<const Value*> args;
     SourceLocation loc;
   };
 
@@ -126,32 +128,32 @@ class Interpreter {
   // State transition for statements.
   auto StepStmt() -> Transition;
 
-  void InitGlobals(const std::vector<Ptr<const Declaration>>& fs);
+  void InitGlobals(const std::vector<Nonnull<const Declaration*>>& fs);
   auto CurrentEnv() -> Env;
   auto GetFromEnv(SourceLocation loc, const std::string& name) -> Address;
 
-  void DeallocateScope(Ptr<Scope> scope);
-  void DeallocateLocals(Ptr<Frame> frame);
+  void DeallocateScope(Nonnull<Scope*> scope);
+  void DeallocateLocals(Nonnull<Frame*> frame);
 
-  auto CreateTuple(Ptr<Action> act, Ptr<const Expression> exp)
-      -> Ptr<const Value>;
+  auto CreateTuple(Nonnull<Action*> act, Nonnull<const Expression*> exp)
+      -> Nonnull<const Value*>;
 
-  auto EvalPrim(Operator op, const std::vector<Ptr<const Value>>& args,
-                SourceLocation loc) -> Ptr<const Value>;
+  auto EvalPrim(Operator op, const std::vector<Nonnull<const Value*>>& args,
+                SourceLocation loc) -> Nonnull<const Value*>;
 
-  void PatternAssignment(Ptr<const Value> pat, Ptr<const Value> val,
+  void PatternAssignment(Nonnull<const Value*> pat, Nonnull<const Value*> val,
                          SourceLocation loc);
 
   void PrintState(llvm::raw_ostream& out);
 
-  Ptr<Arena> arena;
+  Nonnull<Arena*> arena;
 
   // Globally-defined entities, such as functions, structs, or choices.
   Env globals;
 
-  Stack<Ptr<Frame>> stack;
+  Stack<Nonnull<Frame*>> stack;
   Heap heap;
-  std::optional<Ptr<const Value>> program_value;
+  std::optional<Nonnull<const Value*>> program_value;
 };
 
 }  // namespace Carbon

+ 67 - 62
executable_semantics/interpreter/type_checker.cpp

@@ -33,7 +33,8 @@ void PrintTypeEnv(TypeEnv types, llvm::raw_ostream& out) {
 }
 
 static void ExpectType(SourceLocation loc, const std::string& context,
-                       Ptr<const Value> expected, Ptr<const Value> actual) {
+                       Nonnull<const Value*> expected,
+                       Nonnull<const Value*> actual) {
   if (!TypeEqual(expected, actual)) {
     FATAL_COMPILATION_ERROR(loc) << "type error in " << context << "\n"
                                  << "expected: " << *expected << "\n"
@@ -42,7 +43,7 @@ static void ExpectType(SourceLocation loc, const std::string& context,
 }
 
 static void ExpectPointerType(SourceLocation loc, const std::string& context,
-                              Ptr<const Value> actual) {
+                              Nonnull<const Value*> actual) {
   if (actual->Tag() != Value::Kind::PointerType) {
     FATAL_COMPILATION_ERROR(loc) << "type error in " << context << "\n"
                                  << "expected a pointer type\n"
@@ -50,8 +51,8 @@ static void ExpectPointerType(SourceLocation loc, const std::string& context,
   }
 }
 
-auto TypeChecker::ReifyType(Ptr<const Value> t, SourceLocation loc)
-    -> Ptr<const Expression> {
+auto TypeChecker::ReifyType(Nonnull<const Value*> t, SourceLocation loc)
+    -> Nonnull<const Expression*> {
   switch (t->Tag()) {
     case Value::Kind::IntType:
       return arena->New<IntTypeLiteral>(loc);
@@ -82,7 +83,7 @@ auto TypeChecker::ReifyType(Ptr<const Value> t, SourceLocation loc)
     case Value::Kind::PointerType:
       return arena->New<PrimitiveOperatorExpression>(
           loc, Operator::Ptr,
-          std::vector<Ptr<const Expression>>(
+          std::vector<Nonnull<const Expression*>>(
               {ReifyType(cast<PointerType>(*t).Type(), loc)}));
     case Value::Kind::VariableType:
       return arena->New<IdentifierExpression>(loc,
@@ -111,12 +112,12 @@ auto TypeChecker::ReifyType(Ptr<const Value> t, SourceLocation loc)
 // The `deduced` parameter is an accumulator, that is, it holds the
 // results so-far.
 static auto ArgumentDeduction(SourceLocation loc, TypeEnv deduced,
-                              Ptr<const Value> param, Ptr<const Value> arg)
-    -> TypeEnv {
+                              Nonnull<const Value*> param,
+                              Nonnull<const Value*> arg) -> TypeEnv {
   switch (param->Tag()) {
     case Value::Kind::VariableType: {
       const auto& var_type = cast<VariableType>(*param);
-      std::optional<Ptr<const Value>> d = deduced.Get(var_type.Name());
+      std::optional<Nonnull<const Value*>> d = deduced.Get(var_type.Name());
       if (!d) {
         deduced.Set(var_type.Name(), arg);
       } else {
@@ -192,11 +193,11 @@ static auto ArgumentDeduction(SourceLocation loc, TypeEnv deduced,
   }
 }
 
-auto TypeChecker::Substitute(TypeEnv dict, Ptr<const Value> type)
-    -> Ptr<const Value> {
+auto TypeChecker::Substitute(TypeEnv dict, Nonnull<const Value*> type)
+    -> Nonnull<const Value*> {
   switch (type->Tag()) {
     case Value::Kind::VariableType: {
-      std::optional<Ptr<const Value>> t =
+      std::optional<Nonnull<const Value*>> t =
           dict.Get(cast<VariableType>(*type).Name());
       if (!t) {
         return type;
@@ -247,7 +248,7 @@ auto TypeChecker::Substitute(TypeEnv dict, Ptr<const Value> type)
   }
 }
 
-auto TypeChecker::TypeCheckExp(Ptr<const Expression> e, TypeEnv types,
+auto TypeChecker::TypeCheckExp(Nonnull<const Expression*> e, TypeEnv types,
                                Env values) -> TCExpression {
   if (tracing_output) {
     llvm::outs() << "checking expression " << *e << "\ntypes: ";
@@ -267,7 +268,7 @@ auto TypeChecker::TypeCheckExp(Ptr<const Expression> e, TypeEnv types,
               cast<IntValue>(*interpreter.InterpExp(values, index.Offset()))
                   .Val();
           std::string f = std::to_string(i);
-          std::optional<Ptr<const Value>> field_t =
+          std::optional<Nonnull<const Value*>> field_t =
               cast<TupleValue>(*t).FindField(f);
           if (!field_t) {
             FATAL_COMPILATION_ERROR(e->SourceLoc())
@@ -306,16 +307,18 @@ auto TypeChecker::TypeCheckExp(Ptr<const Expression> e, TypeEnv types,
           // Search for a field
           for (auto& field : t_class.Fields()) {
             if (access.Field() == field.first) {
-              Ptr<const Expression> new_e = arena->New<FieldAccessExpression>(
-                  e->SourceLoc(), res.exp, access.Field());
+              Nonnull<const Expression*> new_e =
+                  arena->New<FieldAccessExpression>(e->SourceLoc(), res.exp,
+                                                    access.Field());
               return TCExpression(new_e, field.second, res.types);
             }
           }
           // Search for a method
           for (auto& method : t_class.Methods()) {
             if (access.Field() == method.first) {
-              Ptr<const Expression> new_e = arena->New<FieldAccessExpression>(
-                  e->SourceLoc(), res.exp, access.Field());
+              Nonnull<const Expression*> new_e =
+                  arena->New<FieldAccessExpression>(e->SourceLoc(), res.exp,
+                                                    access.Field());
               return TCExpression(new_e, method.second, res.types);
             }
           }
@@ -340,8 +343,9 @@ auto TypeChecker::TypeCheckExp(Ptr<const Expression> e, TypeEnv types,
           const auto& choice = cast<ChoiceType>(*t);
           for (const auto& vt : choice.Alternatives()) {
             if (access.Field() == vt.first) {
-              Ptr<const Expression> new_e = arena->New<FieldAccessExpression>(
-                  e->SourceLoc(), res.exp, access.Field());
+              Nonnull<const Expression*> new_e =
+                  arena->New<FieldAccessExpression>(e->SourceLoc(), res.exp,
+                                                    access.Field());
               auto fun_ty = arena->New<FunctionType>(
                   std::vector<GenericBinding>(), vt.second, t);
               return TCExpression(new_e, fun_ty, res.types);
@@ -359,7 +363,7 @@ auto TypeChecker::TypeCheckExp(Ptr<const Expression> e, TypeEnv types,
     }
     case Expression::Kind::IdentifierExpression: {
       const auto& ident = cast<IdentifierExpression>(*e);
-      std::optional<Ptr<const Value>> type = types.Get(ident.Name());
+      std::optional<Nonnull<const Value*>> type = types.Get(ident.Name());
       if (type) {
         return TCExpression(e, *type, types);
       } else {
@@ -373,10 +377,10 @@ auto TypeChecker::TypeCheckExp(Ptr<const Expression> e, TypeEnv types,
       return TCExpression(e, arena->New<BoolType>(), types);
     case Expression::Kind::PrimitiveOperatorExpression: {
       const auto& op = cast<PrimitiveOperatorExpression>(*e);
-      std::vector<Ptr<const Expression>> es;
-      std::vector<Ptr<const Value>> ts;
+      std::vector<Nonnull<const Expression*>> es;
+      std::vector<Nonnull<const Value*>> ts;
       auto new_types = types;
-      for (Ptr<const Expression> argument : op.Arguments()) {
+      for (Nonnull<const Expression*> argument : op.Arguments()) {
         auto res = TypeCheckExp(argument, types, values);
         new_types = res.types;
         es.push_back(res.exp);
@@ -494,10 +498,9 @@ auto TypeChecker::TypeCheckExp(Ptr<const Expression> e, TypeEnv types,
   }
 }
 
-auto TypeChecker::TypeCheckPattern(Ptr<const Pattern> p, TypeEnv types,
-                                   Env values,
-                                   std::optional<Ptr<const Value>> expected)
-    -> TCPattern {
+auto TypeChecker::TypeCheckPattern(
+    Nonnull<const Pattern*> p, TypeEnv types, Env values,
+    std::optional<Nonnull<const Value*>> expected) -> TCPattern {
   if (tracing_output) {
     llvm::outs() << "checking pattern " << *p;
     if (expected) {
@@ -517,7 +520,7 @@ auto TypeChecker::TypeCheckPattern(Ptr<const Pattern> p, TypeEnv types,
       const auto& binding = cast<BindingPattern>(*p);
       TCPattern binding_type_result =
           TypeCheckPattern(binding.Type(), types, values, std::nullopt);
-      Ptr<const Value> type =
+      Nonnull<const Value*> type =
           interpreter.InterpPattern(values, binding_type_result.pattern);
       if (expected) {
         std::optional<Env> values = interpreter.PatternMatch(
@@ -554,7 +557,7 @@ auto TypeChecker::TypeCheckPattern(Ptr<const Pattern> p, TypeEnv types,
       }
       for (size_t i = 0; i < tuple.Fields().size(); ++i) {
         const TuplePattern::Field& field = tuple.Fields()[i];
-        std::optional<Ptr<const Value>> expected_field_type;
+        std::optional<Nonnull<const Value*>> expected_field_type;
         if (expected) {
           const TupleElement& expected_element =
               cast<TupleValue>(**expected).Elements()[i];
@@ -578,7 +581,7 @@ auto TypeChecker::TypeCheckPattern(Ptr<const Pattern> p, TypeEnv types,
     }
     case Pattern::Kind::AlternativePattern: {
       const auto& alternative = cast<AlternativePattern>(*p);
-      Ptr<const Value> choice_type =
+      Nonnull<const Value*> choice_type =
           interpreter.InterpExp(values, alternative.ChoiceType());
       if (choice_type->Tag() != Value::Kind::ChoiceType) {
         FATAL_COMPILATION_ERROR(alternative.SourceLoc())
@@ -588,7 +591,7 @@ auto TypeChecker::TypeCheckPattern(Ptr<const Pattern> p, TypeEnv types,
         ExpectType(alternative.SourceLoc(), "alternative pattern", *expected,
                    choice_type);
       }
-      std::optional<Ptr<const Value>> parameter_types =
+      std::optional<Nonnull<const Value*>> parameter_types =
           FindInVarValues(alternative.AlternativeName(),
                           cast<ChoiceType>(*choice_type).Alternatives());
       if (parameter_types == std::nullopt) {
@@ -600,7 +603,7 @@ auto TypeChecker::TypeCheckPattern(Ptr<const Pattern> p, TypeEnv types,
                                                values, *parameter_types);
       // TODO: Think about a cleaner way to cast between Ptr types.
       // (multiple TODOs)
-      auto arguments = Ptr<const TuplePattern>(
+      auto arguments = Nonnull<const TuplePattern*>(
           cast<const TuplePattern>(arg_results.pattern));
       return {.pattern = arena->New<AlternativePattern>(
                   alternative.SourceLoc(),
@@ -619,27 +622,27 @@ auto TypeChecker::TypeCheckPattern(Ptr<const Pattern> p, TypeEnv types,
   }
 }
 
-auto TypeChecker::TypeCheckCase(Ptr<const Value> expected,
-                                Ptr<const Pattern> pat,
-                                Ptr<const Statement> body, TypeEnv types,
-                                Env values, Ptr<const Value>& ret_type,
+auto TypeChecker::TypeCheckCase(Nonnull<const Value*> expected,
+                                Nonnull<const Pattern*> pat,
+                                Nonnull<const Statement*> body, TypeEnv types,
+                                Env values, Nonnull<const Value*>& ret_type,
                                 bool is_omitted_ret_type)
-    -> std::pair<Ptr<const Pattern>, Ptr<const Statement>> {
+    -> std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>> {
   auto pat_res = TypeCheckPattern(pat, types, values, expected);
   auto res =
       TypeCheckStmt(body, pat_res.types, values, ret_type, is_omitted_ret_type);
   return std::make_pair(pat, res.stmt);
 }
 
-auto TypeChecker::TypeCheckStmt(Ptr<const Statement> s, TypeEnv types,
-                                Env values, Ptr<const Value>& ret_type,
+auto TypeChecker::TypeCheckStmt(Nonnull<const Statement*> s, TypeEnv types,
+                                Env values, Nonnull<const Value*>& ret_type,
                                 bool is_omitted_ret_type) -> TCStatement {
   switch (s->Tag()) {
     case Statement::Kind::Match: {
       const auto& match = cast<Match>(*s);
       auto res = TypeCheckExp(match.Exp(), types, values);
       auto res_type = res.type;
-      std::vector<std::pair<Ptr<const Pattern>, Ptr<const Statement>>>
+      std::vector<std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>>>
           new_clauses;
       for (auto& clause : match.Clauses()) {
         new_clauses.push_back(TypeCheckCase(res_type, clause.first,
@@ -677,7 +680,7 @@ auto TypeChecker::TypeCheckStmt(Ptr<const Statement> s, TypeEnv types,
     case Statement::Kind::VariableDefinition: {
       const auto& var = cast<VariableDefinition>(*s);
       auto res = TypeCheckExp(var.Init(), types, values);
-      Ptr<const Value> rhs_ty = res.type;
+      Nonnull<const Value*> rhs_ty = res.type;
       auto lhs_res = TypeCheckPattern(var.Pat(), types, values, rhs_ty);
       auto new_s =
           arena->New<VariableDefinition>(s->SourceLoc(), var.Pat(), res.exp);
@@ -688,7 +691,7 @@ auto TypeChecker::TypeCheckStmt(Ptr<const Statement> s, TypeEnv types,
       auto stmt_res = TypeCheckStmt(seq.Stmt(), types, values, ret_type,
                                     is_omitted_ret_type);
       auto checked_types = stmt_res.types;
-      std::optional<Ptr<const Statement>> next_stmt;
+      std::optional<Nonnull<const Statement*>> next_stmt;
       if (seq.Next()) {
         auto next_res = TypeCheckStmt(*seq.Next(), checked_types, values,
                                       ret_type, is_omitted_ret_type);
@@ -722,7 +725,7 @@ auto TypeChecker::TypeCheckStmt(Ptr<const Statement> s, TypeEnv types,
                  cnd_res.type);
       auto then_res = TypeCheckStmt(if_stmt.ThenStmt(), types, values, ret_type,
                                     is_omitted_ret_type);
-      std::optional<Ptr<const Statement>> else_stmt;
+      std::optional<Nonnull<const Statement*>> else_stmt;
       if (if_stmt.ElseStmt()) {
         auto else_res = TypeCheckStmt(*if_stmt.ElseStmt(), types, values,
                                       ret_type, is_omitted_ret_type);
@@ -777,8 +780,8 @@ auto TypeChecker::TypeCheckStmt(Ptr<const Statement> s, TypeEnv types,
 }
 
 auto TypeChecker::CheckOrEnsureReturn(
-    std::optional<Ptr<const Statement>> opt_stmt, bool omitted_ret_type,
-    SourceLocation loc) -> Ptr<const Statement> {
+    std::optional<Nonnull<const Statement*>> opt_stmt, bool omitted_ret_type,
+    SourceLocation loc) -> Nonnull<const Statement*> {
   if (!opt_stmt) {
     if (omitted_ret_type) {
       return arena->New<Return>(arena, loc);
@@ -788,11 +791,11 @@ auto TypeChecker::CheckOrEnsureReturn(
              "type without reaching a return statement";
     }
   }
-  Ptr<const Statement> stmt = *opt_stmt;
+  Nonnull<const Statement*> stmt = *opt_stmt;
   switch (stmt->Tag()) {
     case Statement::Kind::Match: {
       const auto& match = cast<Match>(*stmt);
-      std::vector<std::pair<Ptr<const Pattern>, Ptr<const Statement>>>
+      std::vector<std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>>>
           new_clauses;
       for (const auto& clause : match.Clauses()) {
         auto s = CheckOrEnsureReturn(clause.second, omitted_ret_type,
@@ -855,7 +858,8 @@ auto TypeChecker::CheckOrEnsureReturn(
 // TODO: Add checking to function definitions to ensure that
 //   all deduced type parameters will be deduced.
 auto TypeChecker::TypeCheckFunDef(const FunctionDefinition* f, TypeEnv types,
-                                  Env values) -> Ptr<const FunctionDefinition> {
+                                  Env values)
+    -> Nonnull<const FunctionDefinition*> {
   // Bring the deduced parameters into scope
   for (const auto& deduced : f->deduced_parameters) {
     // auto t = interpreter.InterpExp(values, deduced.type);
@@ -873,7 +877,7 @@ auto TypeChecker::TypeCheckFunDef(const FunctionDefinition* f, TypeEnv types,
                arena->New<IntType>(), return_type);
     // TODO: Check that main doesn't have any parameters.
   }
-  std::optional<Ptr<const Statement>> body_stmt;
+  std::optional<Nonnull<const Statement*>> body_stmt;
   if (f->body) {
     auto res = TypeCheckStmt(*f->body, param_res.types, values, return_type,
                              f->is_omitted_return_type);
@@ -889,7 +893,7 @@ auto TypeChecker::TypeCheckFunDef(const FunctionDefinition* f, TypeEnv types,
 
 auto TypeChecker::TypeOfFunDef(TypeEnv types, Env values,
                                const FunctionDefinition* fun_def)
-    -> Ptr<const Value> {
+    -> Nonnull<const Value*> {
   // Bring the deduced parameters into scope
   for (const auto& deduced : fun_def->deduced_parameters) {
     // auto t = interpreter.InterpExp(values, deduced.type);
@@ -911,13 +915,14 @@ auto TypeChecker::TypeOfFunDef(TypeEnv types, Env values,
 }
 
 auto TypeChecker::TypeOfClassDef(const ClassDefinition* sd, TypeEnv /*types*/,
-                                 Env ct_top) -> Ptr<const Value> {
+                                 Env ct_top) -> Nonnull<const Value*> {
   VarValues fields;
   VarValues methods;
-  for (Ptr<const Member> m : sd->members) {
+  for (Nonnull<const Member*> m : sd->members) {
     switch (m->Tag()) {
       case Member::Kind::FieldMember: {
-        Ptr<const BindingPattern> binding = cast<FieldMember>(*m).Binding();
+        Nonnull<const BindingPattern*> binding =
+            cast<FieldMember>(*m).Binding();
         if (!binding->Name().has_value()) {
           FATAL_COMPILATION_ERROR(binding->SourceLoc())
               << "Struct members must have names";
@@ -945,7 +950,7 @@ static auto GetName(const Declaration& d) -> const std::string& {
     case Declaration::Kind::ChoiceDeclaration:
       return cast<ChoiceDeclaration>(d).Name();
     case Declaration::Kind::VariableDeclaration: {
-      Ptr<const BindingPattern> binding =
+      Nonnull<const BindingPattern*> binding =
           cast<VariableDeclaration>(d).Binding();
       if (!binding->Name().has_value()) {
         FATAL_COMPILATION_ERROR(binding->SourceLoc())
@@ -956,9 +961,9 @@ static auto GetName(const Declaration& d) -> const std::string& {
   }
 }
 
-auto TypeChecker::MakeTypeChecked(const Ptr<const Declaration> d,
+auto TypeChecker::MakeTypeChecked(const Nonnull<const Declaration*> d,
                                   const TypeEnv& types, const Env& values)
-    -> Ptr<const Declaration> {
+    -> Nonnull<const Declaration*> {
   switch (d->Tag()) {
     case Declaration::Kind::FunctionDeclaration:
       return arena->New<FunctionDeclaration>(TypeCheckFunDef(
@@ -967,8 +972,8 @@ auto TypeChecker::MakeTypeChecked(const Ptr<const Declaration> d,
     case Declaration::Kind::ClassDeclaration: {
       const ClassDefinition& class_def =
           cast<ClassDeclaration>(*d).Definition();
-      std::vector<Ptr<Member>> fields;
-      for (Ptr<Member> m : class_def.members) {
+      std::vector<Nonnull<Member*>> fields;
+      for (Nonnull<Member*> m : class_def.members) {
         switch (m->Tag()) {
           case Member::Kind::FieldMember:
             // TODO: Interpret the type expression and store the result.
@@ -998,7 +1003,7 @@ auto TypeChecker::MakeTypeChecked(const Ptr<const Declaration> d,
         FATAL_COMPILATION_ERROR(var.SourceLoc())
             << "Type of a top-level variable must be an expression.";
       }
-      Ptr<const Value> declared_type =
+      Nonnull<const Value*> declared_type =
           interpreter.InterpExp(values, binding_type->Expression());
       ExpectType(var.SourceLoc(), "initializer of variable", declared_type,
                  type_checked_initializer.type);
@@ -1053,9 +1058,9 @@ void TypeChecker::TopLevel(const Declaration& d, TypeCheckContext* tops) {
       const auto& var = cast<VariableDeclaration>(d);
       // Associate the variable name with it's declared type in the
       // compile-time symbol table.
-      Ptr<const Expression> type =
+      Nonnull<const Expression*> type =
           cast<ExpressionPattern>(*var.Binding()->Type()).Expression();
-      Ptr<const Value> declared_type =
+      Nonnull<const Value*> declared_type =
           interpreter.InterpExp(tops->values, type);
       tops->types.Set(*var.Binding()->Name(), declared_type);
       break;
@@ -1063,7 +1068,7 @@ void TypeChecker::TopLevel(const Declaration& d, TypeCheckContext* tops) {
   }
 }
 
-auto TypeChecker::TopLevel(const std::vector<Ptr<const Declaration>>& fs)
+auto TypeChecker::TopLevel(const std::vector<Nonnull<const Declaration*>>& fs)
     -> TypeCheckContext {
   TypeCheckContext tops(arena);
   bool found_main = false;

+ 37 - 31
executable_semantics/interpreter/type_checker.h

@@ -16,14 +16,15 @@
 
 namespace Carbon {
 
-using TypeEnv = Dictionary<std::string, Ptr<const Value>>;
+using TypeEnv = Dictionary<std::string, Nonnull<const Value*>>;
 
 class TypeChecker {
  public:
-  explicit TypeChecker(Ptr<Arena> arena) : arena(arena), interpreter(arena) {}
+  explicit TypeChecker(Nonnull<Arena*> arena)
+      : arena(arena), interpreter(arena) {}
 
   struct TypeCheckContext {
-    TypeCheckContext(Ptr<Arena> arena) : types(arena), values(arena) {}
+    TypeCheckContext(Nonnull<Arena*> arena) : types(arena), values(arena) {}
 
     // Symbol table mapping names of runtime entities to their type.
     TypeEnv types;
@@ -31,33 +32,35 @@ class TypeChecker {
     Env values;
   };
 
-  auto MakeTypeChecked(const Ptr<const Declaration> d, const TypeEnv& types,
-                       const Env& values) -> Ptr<const Declaration>;
+  auto MakeTypeChecked(const Nonnull<const Declaration*> d,
+                       const TypeEnv& types, const Env& values)
+      -> Nonnull<const Declaration*>;
 
-  auto TopLevel(const std::vector<Ptr<const Declaration>>& fs)
+  auto TopLevel(const std::vector<Nonnull<const Declaration*>>& fs)
       -> TypeCheckContext;
 
  private:
   struct TCExpression {
-    TCExpression(Ptr<const Expression> e, Ptr<const Value> t, TypeEnv types)
+    TCExpression(Nonnull<const Expression*> e, Nonnull<const Value*> t,
+                 TypeEnv types)
         : exp(e), type(t), types(types) {}
 
-    Ptr<const Expression> exp;
-    Ptr<const Value> type;
+    Nonnull<const Expression*> exp;
+    Nonnull<const Value*> type;
     TypeEnv types;
   };
 
   struct TCPattern {
-    Ptr<const Pattern> pattern;
-    Ptr<const Value> type;
+    Nonnull<const Pattern*> pattern;
+    Nonnull<const Value*> type;
     TypeEnv types;
   };
 
   struct TCStatement {
-    TCStatement(Ptr<const Statement> s, TypeEnv types)
+    TCStatement(Nonnull<const Statement*> s, TypeEnv types)
         : stmt(s), types(types) {}
 
-    Ptr<const Statement> stmt;
+    Nonnull<const Statement*> stmt;
     TypeEnv types;
   };
 
@@ -72,15 +75,16 @@ class TypeChecker {
   // types maps variable names to the type of their run-time value.
   // values maps variable names to their compile-time values. It is not
   //    directly used in this function but is passed to InterExp.
-  auto TypeCheckExp(Ptr<const Expression> e, TypeEnv types, Env values)
+  auto TypeCheckExp(Nonnull<const Expression*> e, TypeEnv types, Env values)
       -> TCExpression;
 
   // Equivalent to TypeCheckExp, but operates on Patterns instead of
   // Expressions. `expected` is the type that this pattern is expected to have,
   // if the surrounding context gives us that information. Otherwise, it is
   // nullopt.
-  auto TypeCheckPattern(Ptr<const Pattern> p, TypeEnv types, Env values,
-                        std::optional<Ptr<const Value>> expected) -> TCPattern;
+  auto TypeCheckPattern(Nonnull<const Pattern*> p, TypeEnv types, Env values,
+                        std::optional<Nonnull<const Value*>> expected)
+      -> TCPattern;
 
   // TypeCheckStmt performs semantic analysis on a statement.  It returns a new
   // version of the statement and a new type environment.
@@ -89,36 +93,38 @@ class TypeChecker {
   // declared return type of the enclosing function definition.  If the return
   // type is "auto", then the return type is inferred from the first return
   // statement.
-  auto TypeCheckStmt(Ptr<const Statement> s, TypeEnv types, Env values,
-                     Ptr<const Value>& ret_type, bool is_omitted_ret_type)
+  auto TypeCheckStmt(Nonnull<const Statement*> s, TypeEnv types, Env values,
+                     Nonnull<const Value*>& ret_type, bool is_omitted_ret_type)
       -> TCStatement;
 
   auto TypeCheckFunDef(const FunctionDefinition* f, TypeEnv types, Env values)
-      -> Ptr<const FunctionDefinition>;
+      -> Nonnull<const FunctionDefinition*>;
 
-  auto TypeCheckCase(Ptr<const Value> expected, Ptr<const Pattern> pat,
-                     Ptr<const Statement> body, TypeEnv types, Env values,
-                     Ptr<const Value>& ret_type, bool is_omitted_ret_type)
-      -> std::pair<Ptr<const Pattern>, Ptr<const Statement>>;
+  auto TypeCheckCase(Nonnull<const Value*> expected,
+                     Nonnull<const Pattern*> pat,
+                     Nonnull<const Statement*> body, TypeEnv types, Env values,
+                     Nonnull<const Value*>& ret_type, bool is_omitted_ret_type)
+      -> std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>>;
 
   auto TypeOfFunDef(TypeEnv types, Env values,
-                    const FunctionDefinition* fun_def) -> Ptr<const Value>;
+                    const FunctionDefinition* fun_def) -> Nonnull<const Value*>;
   auto TypeOfClassDef(const ClassDefinition* sd, TypeEnv /*types*/, Env ct_top)
-      -> Ptr<const Value>;
+      -> Nonnull<const Value*>;
 
   void TopLevel(const Declaration& d, TypeCheckContext* tops);
 
-  auto CheckOrEnsureReturn(std::optional<Ptr<const Statement>> opt_stmt,
+  auto CheckOrEnsureReturn(std::optional<Nonnull<const Statement*>> opt_stmt,
                            bool omitted_ret_type, SourceLocation loc)
-      -> Ptr<const Statement>;
+      -> Nonnull<const Statement*>;
 
   // Reify type to type expression.
-  auto ReifyType(Ptr<const Value> t, SourceLocation loc)
-      -> Ptr<const Expression>;
+  auto ReifyType(Nonnull<const Value*> t, SourceLocation loc)
+      -> Nonnull<const Expression*>;
 
-  auto Substitute(TypeEnv dict, Ptr<const Value> type) -> Ptr<const Value>;
+  auto Substitute(TypeEnv dict, Nonnull<const Value*> type)
+      -> Nonnull<const Value*>;
 
-  Ptr<Arena> arena;
+  Nonnull<Arena*> arena;
   Interpreter interpreter;
 };
 

+ 30 - 27
executable_semantics/interpreter/value.cpp

@@ -18,7 +18,7 @@ namespace Carbon {
 using llvm::cast;
 
 auto FindInVarValues(const std::string& field, const VarValues& inits)
-    -> std::optional<Ptr<const Value>> {
+    -> std::optional<Nonnull<const Value*>> {
   for (auto& i : inits) {
     if (i.first == field) {
       return i.second;
@@ -45,7 +45,7 @@ auto FieldsEqual(const VarValues& ts1, const VarValues& ts2) -> bool {
 }
 
 auto TupleValue::FindField(const std::string& name) const
-    -> std::optional<Ptr<const Value>> {
+    -> std::optional<Nonnull<const Value*>> {
   for (const TupleElement& element : elements) {
     if (element.name == name) {
       return element.value;
@@ -56,11 +56,12 @@ auto TupleValue::FindField(const std::string& name) const
 
 namespace {
 
-auto GetMember(Ptr<Arena> arena, Ptr<const Value> v, const std::string& f,
-               SourceLocation loc) -> Ptr<const Value> {
+auto GetMember(Nonnull<Arena*> arena, Nonnull<const Value*> v,
+               const std::string& f, SourceLocation loc)
+    -> Nonnull<const Value*> {
   switch (v->Tag()) {
     case Value::Kind::StructValue: {
-      std::optional<Ptr<const Value>> field =
+      std::optional<Nonnull<const Value*>> field =
           cast<TupleValue>(*cast<StructValue>(*v).Inits()).FindField(f);
       if (field == std::nullopt) {
         FATAL_RUNTIME_ERROR(loc) << "member " << f << " not in " << *v;
@@ -68,7 +69,8 @@ auto GetMember(Ptr<Arena> arena, Ptr<const Value> v, const std::string& f,
       return *field;
     }
     case Value::Kind::TupleValue: {
-      std::optional<Ptr<const Value>> field = cast<TupleValue>(*v).FindField(f);
+      std::optional<Nonnull<const Value*>> field =
+          cast<TupleValue>(*v).FindField(f);
       if (!field) {
         FATAL_RUNTIME_ERROR(loc) << "field " << f << " not in " << *v;
       }
@@ -88,9 +90,9 @@ auto GetMember(Ptr<Arena> arena, Ptr<const Value> v, const std::string& f,
 
 }  // namespace
 
-auto Value::GetField(Ptr<Arena> arena, const FieldPath& path,
-                     SourceLocation loc) const -> Ptr<const Value> {
-  Ptr<const Value> value(this);
+auto Value::GetField(Nonnull<Arena*> arena, const FieldPath& path,
+                     SourceLocation loc) const -> Nonnull<const Value*> {
+  Nonnull<const Value*> value(this);
   for (const std::string& field : path.components) {
     value = GetMember(arena, value, field, loc);
   }
@@ -99,11 +101,11 @@ auto Value::GetField(Ptr<Arena> arena, const FieldPath& path,
 
 namespace {
 
-auto SetFieldImpl(Ptr<Arena> arena, Ptr<const Value> value,
+auto SetFieldImpl(Nonnull<Arena*> arena, Nonnull<const Value*> value,
                   std::vector<std::string>::const_iterator path_begin,
                   std::vector<std::string>::const_iterator path_end,
-                  Ptr<const Value> field_value, SourceLocation loc)
-    -> Ptr<const Value> {
+                  Nonnull<const Value*> field_value, SourceLocation loc)
+    -> Nonnull<const Value*> {
   if (path_begin == path_end) {
     return field_value;
   }
@@ -133,11 +135,12 @@ auto SetFieldImpl(Ptr<Arena> arena, Ptr<const Value> value,
 
 }  // namespace
 
-auto Value::SetField(Ptr<Arena> arena, const FieldPath& path,
-                     Ptr<const Value> field_value, SourceLocation loc) const
-    -> Ptr<const Value> {
-  return SetFieldImpl(arena, Ptr<const Value>(this), path.components.begin(),
-                      path.components.end(), field_value, loc);
+auto Value::SetField(Nonnull<Arena*> arena, const FieldPath& path,
+                     Nonnull<const Value*> field_value,
+                     SourceLocation loc) const -> Nonnull<const Value*> {
+  return SetFieldImpl(arena, Nonnull<const Value*>(this),
+                      path.components.begin(), path.components.end(),
+                      field_value, loc);
 }
 
 void Value::Print(llvm::raw_ostream& out) const {
@@ -237,7 +240,7 @@ void Value::Print(llvm::raw_ostream& out) const {
     case Value::Kind::ContinuationValue: {
       out << "{";
       llvm::ListSeparator sep(" :: ");
-      for (Ptr<Frame> frame : cast<ContinuationValue>(*this).Stack()) {
+      for (Nonnull<Frame*> frame : cast<ContinuationValue>(*this).Stack()) {
         out << sep << *frame;
       }
       out << "}";
@@ -254,8 +257,8 @@ void Value::Print(llvm::raw_ostream& out) const {
   }
 }
 
-auto CopyVal(Ptr<Arena> arena, Ptr<const Value> val, SourceLocation loc)
-    -> Ptr<const Value> {
+auto CopyVal(Nonnull<Arena*> arena, Nonnull<const Value*> val,
+             SourceLocation loc) -> Nonnull<const Value*> {
   switch (val->Tag()) {
     case Value::Kind::TupleValue: {
       std::vector<TupleElement> elements;
@@ -267,12 +270,12 @@ auto CopyVal(Ptr<Arena> arena, Ptr<const Value> val, SourceLocation loc)
     }
     case Value::Kind::AlternativeValue: {
       const auto& alt = cast<AlternativeValue>(*val);
-      Ptr<const Value> arg = CopyVal(arena, alt.Argument(), loc);
+      Nonnull<const Value*> arg = CopyVal(arena, alt.Argument(), loc);
       return arena->New<AlternativeValue>(alt.AltName(), alt.ChoiceName(), arg);
     }
     case Value::Kind::StructValue: {
       const auto& s = cast<StructValue>(*val);
-      Ptr<const Value> inits = CopyVal(arena, s.Inits(), loc);
+      Nonnull<const Value*> inits = CopyVal(arena, s.Inits(), loc);
       return arena->New<StructValue>(s.Type(), inits);
     }
     case Value::Kind::IntValue:
@@ -322,7 +325,7 @@ auto CopyVal(Ptr<Arena> arena, Ptr<const Value> val, SourceLocation loc)
   }
 }
 
-auto TypeEqual(Ptr<const Value> t1, Ptr<const Value> t2) -> bool {
+auto TypeEqual(Nonnull<const Value*> t1, Nonnull<const Value*> t2) -> bool {
   if (t1->Tag() != t2->Tag()) {
     return false;
   }
@@ -394,8 +397,8 @@ static auto FieldsValueEqual(const std::vector<TupleElement>& ts1,
 // Returns true if the two values are equal and returns false otherwise.
 //
 // This function implements the `==` operator of Carbon.
-auto ValueEqual(Ptr<const Value> v1, Ptr<const Value> v2, SourceLocation loc)
-    -> bool {
+auto ValueEqual(Nonnull<const Value*> v1, Nonnull<const Value*> v2,
+                SourceLocation loc) -> bool {
   if (v1->Tag() != v2->Tag()) {
     return false;
   }
@@ -407,9 +410,9 @@ auto ValueEqual(Ptr<const Value> v1, Ptr<const Value> v2, SourceLocation loc)
     case Value::Kind::PointerValue:
       return cast<PointerValue>(*v1).Val() == cast<PointerValue>(*v2).Val();
     case Value::Kind::FunctionValue: {
-      std::optional<Ptr<const Statement>> body1 =
+      std::optional<Nonnull<const Statement*>> body1 =
           cast<FunctionValue>(*v1).Body();
-      std::optional<Ptr<const Statement>> body2 =
+      std::optional<Nonnull<const Statement*>> body2 =
           cast<FunctionValue>(*v2).Body();
       return body1.has_value() == body2.has_value() &&
              (!body1.has_value() || *body1 == *body2);

+ 45 - 45
executable_semantics/interpreter/value.h

@@ -68,14 +68,14 @@ class Value {
 
   // Returns the sub-Value specified by `path`, which must be a valid field
   // path for *this.
-  auto GetField(Ptr<Arena> arena, const FieldPath& path,
-                SourceLocation loc) const -> Ptr<const Value>;
+  auto GetField(Nonnull<Arena*> arena, const FieldPath& path,
+                SourceLocation loc) const -> Nonnull<const Value*>;
 
   // Returns a copy of *this, but with the sub-Value specified by `path`
   // set to `field_value`. `path` must be a valid field path for *this.
-  auto SetField(Ptr<Arena> arena, const FieldPath& path,
-                Ptr<const Value> field_value, SourceLocation loc) const
-      -> Ptr<const Value>;
+  auto SetField(Nonnull<Arena*> arena, const FieldPath& path,
+                Nonnull<const Value*> field_value, SourceLocation loc) const
+      -> Nonnull<const Value*>;
 
  protected:
   // Constructs a Value. `tag` must be the enumerator corresponding to the
@@ -86,10 +86,10 @@ class Value {
   const Kind tag;
 };
 
-using VarValues = std::vector<std::pair<std::string, Ptr<const Value>>>;
+using VarValues = std::vector<std::pair<std::string, Nonnull<const Value*>>>;
 
 auto FindInVarValues(const std::string& field, const VarValues& inits)
-    -> std::optional<Ptr<const Value>>;
+    -> std::optional<Nonnull<const Value*>>;
 auto FieldsEqual(const VarValues& ts1, const VarValues& ts2) -> bool;
 
 // A TupleElement represents the value of a single tuple field.
@@ -98,7 +98,7 @@ struct TupleElement {
   std::string name;
 
   // The field's value.
-  Ptr<const Value> value;
+  Nonnull<const Value*> value;
 };
 
 struct Frame;  // Used by continuation.
@@ -121,8 +121,8 @@ class IntValue : public Value {
 // A function value.
 class FunctionValue : public Value {
  public:
-  FunctionValue(std::string name, Ptr<const Value> param,
-                std::optional<Ptr<const Statement>> body)
+  FunctionValue(std::string name, Nonnull<const Value*> param,
+                std::optional<Nonnull<const Statement*>> body)
       : Value(Kind::FunctionValue),
         name(std::move(name)),
         param(param),
@@ -133,13 +133,13 @@ class FunctionValue : public Value {
   }
 
   auto Name() const -> const std::string& { return name; }
-  auto Param() const -> Ptr<const Value> { return param; }
-  auto Body() const -> std::optional<Ptr<const Statement>> { return body; }
+  auto Param() const -> Nonnull<const Value*> { return param; }
+  auto Body() const -> std::optional<Nonnull<const Statement*>> { return body; }
 
  private:
   std::string name;
-  Ptr<const Value> param;
-  std::optional<Ptr<const Statement>> body;
+  Nonnull<const Value*> param;
+  std::optional<Nonnull<const Statement*>> body;
 };
 
 // A pointer value.
@@ -176,19 +176,19 @@ class BoolValue : public Value {
 // A function value.
 class StructValue : public Value {
  public:
-  StructValue(Ptr<const Value> type, Ptr<const Value> inits)
+  StructValue(Nonnull<const Value*> type, Nonnull<const Value*> inits)
       : Value(Kind::StructValue), type(type), inits(inits) {}
 
   static auto classof(const Value* value) -> bool {
     return value->Tag() == Kind::StructValue;
   }
 
-  auto Type() const -> Ptr<const Value> { return type; }
-  auto Inits() const -> Ptr<const Value> { return inits; }
+  auto Type() const -> Nonnull<const Value*> { return type; }
+  auto Inits() const -> Nonnull<const Value*> { return inits; }
 
  private:
-  Ptr<const Value> type;
-  Ptr<const Value> inits;
+  Nonnull<const Value*> type;
+  Nonnull<const Value*> inits;
 };
 
 // An alternative constructor value.
@@ -215,7 +215,7 @@ class AlternativeConstructorValue : public Value {
 class AlternativeValue : public Value {
  public:
   AlternativeValue(std::string alt_name, std::string choice_name,
-                   Ptr<const Value> argument)
+                   Nonnull<const Value*> argument)
       : Value(Kind::AlternativeValue),
         alt_name(std::move(alt_name)),
         choice_name(std::move(choice_name)),
@@ -227,21 +227,21 @@ class AlternativeValue : public Value {
 
   auto AltName() const -> const std::string& { return alt_name; }
   auto ChoiceName() const -> const std::string& { return choice_name; }
-  auto Argument() const -> Ptr<const Value> { return argument; }
+  auto Argument() const -> Nonnull<const Value*> { return argument; }
 
  private:
   std::string alt_name;
   std::string choice_name;
-  Ptr<const Value> argument;
+  Nonnull<const Value*> argument;
 };
 
 // A function value.
 class TupleValue : public Value {
  public:
   // An empty tuple, also known as the unit type.
-  static Ptr<const TupleValue> Empty() {
+  static Nonnull<const TupleValue*> Empty() {
     static const TupleValue empty = TupleValue(std::vector<TupleElement>());
-    return Ptr<const TupleValue>(&empty);
+    return Nonnull<const TupleValue*>(&empty);
   }
 
   explicit TupleValue(std::vector<TupleElement> elements)
@@ -256,7 +256,7 @@ class TupleValue : public Value {
   // Returns the value of the field named `name` in this tuple, or
   // nullopt if there is no such field.
   auto FindField(const std::string& name) const
-      -> std::optional<Ptr<const Value>>;
+      -> std::optional<Nonnull<const Value*>>;
 
  private:
   std::vector<TupleElement> elements;
@@ -267,7 +267,7 @@ class BindingPlaceholderValue : public Value {
  public:
   // nullopt represents the `_` placeholder.
   BindingPlaceholderValue(std::optional<std::string> name,
-                          Ptr<const Value> type)
+                          Nonnull<const Value*> type)
       : Value(Kind::BindingPlaceholderValue),
         name(std::move(name)),
         type(type) {}
@@ -277,11 +277,11 @@ class BindingPlaceholderValue : public Value {
   }
 
   auto Name() const -> const std::optional<std::string>& { return name; }
-  auto Type() const -> Ptr<const Value> { return type; }
+  auto Type() const -> Nonnull<const Value*> { return type; }
 
  private:
   std::optional<std::string> name;
-  Ptr<const Value> type;
+  Nonnull<const Value*> type;
 };
 
 // The int type.
@@ -317,8 +317,8 @@ class TypeType : public Value {
 // A function type.
 class FunctionType : public Value {
  public:
-  FunctionType(std::vector<GenericBinding> deduced, Ptr<const Value> param,
-               Ptr<const Value> ret)
+  FunctionType(std::vector<GenericBinding> deduced, Nonnull<const Value*> param,
+               Nonnull<const Value*> ret)
       : Value(Kind::FunctionType),
         deduced(std::move(deduced)),
         param(param),
@@ -329,29 +329,29 @@ class FunctionType : public Value {
   }
 
   auto Deduced() const -> const std::vector<GenericBinding>& { return deduced; }
-  auto Param() const -> Ptr<const Value> { return param; }
-  auto Ret() const -> Ptr<const Value> { return ret; }
+  auto Param() const -> Nonnull<const Value*> { return param; }
+  auto Ret() const -> Nonnull<const Value*> { return ret; }
 
  private:
   std::vector<GenericBinding> deduced;
-  Ptr<const Value> param;
-  Ptr<const Value> ret;
+  Nonnull<const Value*> param;
+  Nonnull<const Value*> ret;
 };
 
 // A pointer type.
 class PointerType : public Value {
  public:
-  explicit PointerType(Ptr<const Value> type)
+  explicit PointerType(Nonnull<const Value*> type)
       : Value(Kind::PointerType), type(type) {}
 
   static auto classof(const Value* value) -> bool {
     return value->Tag() == Kind::PointerType;
   }
 
-  auto Type() const -> Ptr<const Value> { return type; }
+  auto Type() const -> Nonnull<const Value*> { return type; }
 
  private:
-  Ptr<const Value> type;
+  Nonnull<const Value*> type;
 };
 
 // The `auto` type.
@@ -436,17 +436,17 @@ class VariableType : public Value {
 // A first-class continuation representation of a fragment of the stack.
 class ContinuationValue : public Value {
  public:
-  explicit ContinuationValue(std::vector<Ptr<Frame>> stack)
+  explicit ContinuationValue(std::vector<Nonnull<Frame*>> stack)
       : Value(Kind::ContinuationValue), stack(std::move(stack)) {}
 
   static auto classof(const Value* value) -> bool {
     return value->Tag() == Kind::ContinuationValue;
   }
 
-  auto Stack() const -> const std::vector<Ptr<Frame>>& { return stack; }
+  auto Stack() const -> const std::vector<Nonnull<Frame*>>& { return stack; }
 
  private:
-  std::vector<Ptr<Frame>> stack;
+  std::vector<Nonnull<Frame*>> stack;
 };
 
 // The String type.
@@ -475,12 +475,12 @@ class StringValue : public Value {
   std::string val;
 };
 
-auto CopyVal(Ptr<Arena> arena, Ptr<const Value> val, SourceLocation loc)
-    -> Ptr<const Value>;
+auto CopyVal(Nonnull<Arena*> arena, Nonnull<const Value*> val,
+             SourceLocation loc) -> Nonnull<const Value*>;
 
-auto TypeEqual(Ptr<const Value> t1, Ptr<const Value> t2) -> bool;
-auto ValueEqual(Ptr<const Value> v1, Ptr<const Value> v2, SourceLocation loc)
-    -> bool;
+auto TypeEqual(Nonnull<const Value*> t1, Nonnull<const Value*> t2) -> bool;
+auto ValueEqual(Nonnull<const Value*> v1, Nonnull<const Value*> v2,
+                SourceLocation loc) -> bool;
 
 }  // namespace Carbon
 

+ 1 - 1
executable_semantics/syntax/parse.cpp

@@ -13,7 +13,7 @@
 
 namespace Carbon {
 
-auto Parse(Ptr<Arena> arena, const std::string& input_file_name)
+auto Parse(Nonnull<Arena*> arena, const std::string& input_file_name)
     -> std::variant<AST, SyntaxErrorCode> {
   FILE* input_file = fopen(input_file_name.c_str(), "r");
   if (input_file == nullptr) {

+ 1 - 1
executable_semantics/syntax/parse.h

@@ -18,7 +18,7 @@ using SyntaxErrorCode = int;
 
 // Returns the AST representing the contents of the named file, or an error code
 // if parsing fails. Allocations go into the provided arena.
-auto Parse(Ptr<Arena> arena, const std::string& input_file_name)
+auto Parse(Nonnull<Arena*> arena, const std::string& input_file_name)
     -> std::variant<Carbon::AST, SyntaxErrorCode>;
 
 }  // namespace Carbon

+ 5 - 5
executable_semantics/syntax/parse_and_lex_context.h

@@ -17,7 +17,7 @@ namespace Carbon {
 class ParseAndLexContext {
  public:
   // Creates an instance analyzing the given input file.
-  ParseAndLexContext(Ptr<const std::string> input_file_name)
+  ParseAndLexContext(Nonnull<const std::string*> input_file_name)
       : input_file_name(input_file_name) {}
 
   // Writes a syntax error diagnostic containing message to standard error.
@@ -34,15 +34,15 @@ class ParseAndLexContext {
  private:
   // A path to the file processed, relative to the current working directory
   // when *this is called.
-  Ptr<const std::string> input_file_name;
+  Nonnull<const std::string*> input_file_name;
 };
 
 }  // namespace Carbon
 
 // Gives flex the yylex prototype we want.
-#define YY_DECL                                                       \
-  Carbon::Parser::symbol_type yylex(Carbon::Ptr<Carbon::Arena> arena, \
-                                    yyscan_t yyscanner,               \
+#define YY_DECL                                                            \
+  Carbon::Parser::symbol_type yylex(Carbon::Nonnull<Carbon::Arena*> arena, \
+                                    yyscan_t yyscanner,                    \
                                     Carbon::ParseAndLexContext& context)
 
 // Declares yylex for the parser's sake.

+ 49 - 45
executable_semantics/syntax/parser.ypp

@@ -38,7 +38,7 @@
 // thus available to its methods.
 
 // "inout" parameters passed to both the parser and the lexer.
-%param {Ptr<Arena> arena}
+%param {Nonnull<Arena*> arena}
 %param {yyscan_t yyscanner}
 %param {ParseAndLexContext& context}
 
@@ -98,43 +98,43 @@
 %type <std::vector<LibraryName>> import_directives
 %type <std::string> optional_library_path
 %type <bool> api_or_impl
-%type <BisonWrap<Ptr<const Declaration>>> declaration
-%type <BisonWrap<Ptr<const FunctionDefinition>>> function_declaration
-%type <BisonWrap<Ptr<const FunctionDefinition>>> function_definition
-%type <std::vector<Ptr<const Declaration>>> declaration_list
-%type <BisonWrap<Ptr<const Statement>>> statement
-%type <BisonWrap<Ptr<const Statement>>> if_statement
-%type <std::optional<Ptr<const Statement>>> optional_else
-%type <BisonWrap<std::pair<Ptr<const Expression>, bool>>> return_expression
-%type <BisonWrap<Ptr<const Statement>>> block
-%type <std::optional<Ptr<const Statement>>> statement_list
-%type <BisonWrap<Ptr<const Expression>>> expression
+%type <BisonWrap<Nonnull<const Declaration*>>> declaration
+%type <BisonWrap<Nonnull<const FunctionDefinition*>>> function_declaration
+%type <BisonWrap<Nonnull<const FunctionDefinition*>>> function_definition
+%type <std::vector<Nonnull<const Declaration*>>> declaration_list
+%type <BisonWrap<Nonnull<const Statement*>>> statement
+%type <BisonWrap<Nonnull<const Statement*>>> if_statement
+%type <std::optional<Nonnull<const Statement*>>> optional_else
+%type <BisonWrap<std::pair<Nonnull<const Expression*>, bool>>> return_expression
+%type <BisonWrap<Nonnull<const Statement*>>> block
+%type <std::optional<Nonnull<const Statement*>>> statement_list
+%type <BisonWrap<Nonnull<const Expression*>>> expression
 %type <BisonWrap<GenericBinding>> generic_binding
 %type <std::vector<GenericBinding>> deduced_params
 %type <std::vector<GenericBinding>> deduced_param_list
-%type <BisonWrap<Ptr<const Pattern>>> pattern
-%type <BisonWrap<Ptr<const Pattern>>> non_expression_pattern
-%type <BisonWrap<std::pair<Ptr<const Expression>, bool>>> return_type
-%type <BisonWrap<Ptr<const Expression>>> paren_expression
-%type <BisonWrap<Ptr<const Expression>>> tuple
+%type <BisonWrap<Nonnull<const Pattern*>>> pattern
+%type <BisonWrap<Nonnull<const Pattern*>>> non_expression_pattern
+%type <BisonWrap<std::pair<Nonnull<const Expression*>, bool>>> return_type
+%type <BisonWrap<Nonnull<const Expression*>>> paren_expression
+%type <BisonWrap<Nonnull<const Expression*>>> tuple
 %type <std::optional<std::string>> binding_lhs
-%type <BisonWrap<Ptr<const BindingPattern>>> variable_declaration
-%type <BisonWrap<Ptr<Member>>> member
-%type <std::vector<Ptr<Member>>> member_list
+%type <BisonWrap<Nonnull<const BindingPattern*>>> variable_declaration
+%type <BisonWrap<Nonnull<Member*>>> member
+%type <std::vector<Nonnull<Member*>>> member_list
 %type <BisonWrap<ParenContents<Expression>::Element>> paren_expression_element
 %type <ParenContents<Expression>> paren_expression_base
 %type <ParenContents<Expression>> paren_expression_contents
-%type <BisonWrap<Ptr<const Pattern>>> paren_pattern
-%type <BisonWrap<Ptr<const TuplePattern>>> tuple_pattern
-%type <BisonWrap<Ptr<const TuplePattern>>> maybe_empty_tuple_pattern
+%type <BisonWrap<Nonnull<const Pattern*>>> paren_pattern
+%type <BisonWrap<Nonnull<const TuplePattern*>>> tuple_pattern
+%type <BisonWrap<Nonnull<const TuplePattern*>>> maybe_empty_tuple_pattern
 %type <ParenContents<Pattern>> paren_pattern_base
 %type <BisonWrap<ParenContents<Pattern>::Element>> paren_pattern_element
 %type <ParenContents<Pattern>> paren_pattern_contents
-%type <BisonWrap<std::pair<std::string, Ptr<const Expression>>>> alternative
-%type <std::vector<std::pair<std::string, Ptr<const Expression>>>> alternative_list
-%type <std::vector<std::pair<std::string, Ptr<const Expression>>>> alternative_list_contents
-%type <BisonWrap<std::pair<Ptr<const Pattern>, Ptr<const Statement>>>> clause
-%type <std::vector<std::pair<Ptr<const Pattern>, Ptr<const Statement>>>> clause_list
+%type <BisonWrap<std::pair<std::string, Nonnull<const Expression*>>>> alternative
+%type <std::vector<std::pair<std::string, Nonnull<const Expression*>>>> alternative_list
+%type <std::vector<std::pair<std::string, Nonnull<const Expression*>>>> alternative_list_contents
+%type <BisonWrap<std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>>>> clause
+%type <std::vector<std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>>>> clause_list
 
 %token
   // Most tokens have their spelling defined in lexer.lpp.
@@ -303,61 +303,61 @@ expression:
     {
       $$ = arena->New<PrimitiveOperatorExpression>(
           context.SourceLoc(), Operator::Eq,
-          std::vector<Ptr<const Expression>>({$1, $3}));
+          std::vector<Nonnull<const Expression*>>({$1, $3}));
     }
 | expression PLUS expression
     {
       $$ = arena->New<PrimitiveOperatorExpression>(
           context.SourceLoc(), Operator::Add,
-          std::vector<Ptr<const Expression>>({$1, $3}));
+          std::vector<Nonnull<const Expression*>>({$1, $3}));
     }
 | expression MINUS expression
     {
       $$ = arena->New<PrimitiveOperatorExpression>(
           context.SourceLoc(), Operator::Sub,
-          std::vector<Ptr<const Expression>>({$1, $3}));
+          std::vector<Nonnull<const Expression*>>({$1, $3}));
     }
 | expression BINARY_STAR expression
     {
       $$ = arena->New<PrimitiveOperatorExpression>(
           context.SourceLoc(), Operator::Mul,
-          std::vector<Ptr<const Expression>>({$1, $3}));
+          std::vector<Nonnull<const Expression*>>({$1, $3}));
     }
 | expression AND expression
     {
       $$ = arena->New<PrimitiveOperatorExpression>(
           context.SourceLoc(), Operator::And,
-          std::vector<Ptr<const Expression>>({$1, $3}));
+          std::vector<Nonnull<const Expression*>>({$1, $3}));
     }
 | expression OR expression
     {
       $$ = arena->New<PrimitiveOperatorExpression>(
           context.SourceLoc(), Operator::Or,
-          std::vector<Ptr<const Expression>>({$1, $3}));
+          std::vector<Nonnull<const Expression*>>({$1, $3}));
     }
 | NOT expression
     {
       $$ = arena->New<PrimitiveOperatorExpression>(
           context.SourceLoc(), Operator::Not,
-          std::vector<Ptr<const Expression>>({$2}));
+          std::vector<Nonnull<const Expression*>>({$2}));
     }
 | MINUS expression %prec UNARY_MINUS
     {
       $$ = arena->New<PrimitiveOperatorExpression>(
           context.SourceLoc(), Operator::Neg,
-          std::vector<Ptr<const Expression>>({$2}));
+          std::vector<Nonnull<const Expression*>>({$2}));
     }
 | PREFIX_STAR expression
     {
       $$ = arena->New<PrimitiveOperatorExpression>(
           context.SourceLoc(), Operator::Deref,
-          std::vector<Ptr<const Expression>>({$2}));
+          std::vector<Nonnull<const Expression*>>({$2}));
     }
 | UNARY_STAR expression %prec PREFIX_STAR
     {
       $$ = arena->New<PrimitiveOperatorExpression>(
           context.SourceLoc(), Operator::Deref,
-          std::vector<Ptr<const Expression>>({$2}));
+          std::vector<Nonnull<const Expression*>>({$2}));
     }
 | expression tuple
     { $$ = arena->New<CallExpression>(context.SourceLoc(), $1, $2); }
@@ -365,13 +365,13 @@ expression:
     {
       $$ = arena->New<PrimitiveOperatorExpression>(
           context.SourceLoc(), Operator::Ptr,
-          std::vector<Ptr<const Expression>>({$1}));
+          std::vector<Nonnull<const Expression*>>({$1}));
     }
 | expression UNARY_STAR
     {
       $$ = arena->New<PrimitiveOperatorExpression>(
           context.SourceLoc(), Operator::Ptr,
-          std::vector<Ptr<const Expression>>({$1}));
+          std::vector<Nonnull<const Expression*>>({$1}));
     }
 | FNTY tuple return_type
     {
@@ -502,13 +502,17 @@ maybe_empty_tuple_pattern:
 ;
 clause:
   CASE pattern DOUBLE_ARROW statement
-    { $$ = std::pair<Ptr<const Pattern>, Ptr<const Statement>>($2, $4); }
+    {
+      $$ =
+          std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>>($2, $4);
+    }
 | DEFAULT DOUBLE_ARROW statement
     {
       auto vp = arena -> New<BindingPattern>(
                     context.SourceLoc(), std::nullopt,
                     arena->New<AutoPattern>(context.SourceLoc()));
-      $$ = std::pair<Ptr<const Pattern>, Ptr<const Statement>>(vp, $3);
+      $$ =
+          std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>>(vp, $3);
     }
 ;
 clause_list:
@@ -656,10 +660,10 @@ member_list:
 ;
 alternative:
   identifier tuple
-    { $$ = std::pair<std::string, Ptr<const Expression>>($1, $2); }
+    { $$ = std::pair<std::string, Nonnull<const Expression*>>($1, $2); }
 | identifier
     {
-      $$ = std::pair<std::string, Ptr<const Expression>>(
+      $$ = std::pair<std::string, Nonnull<const Expression*>>(
           $1, arena->New<TupleLiteral>(context.SourceLoc()));
     }
 ;
@@ -698,7 +702,7 @@ declaration_list:
 | declaration_list declaration
     {
       $$ = $1;
-      $$.push_back(Ptr<const Declaration>($2));
+      $$.push_back(Nonnull<const Declaration*>($2));
     }
 ;
 %%