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

Enable readability-qualified-auto (#2314)

As suggested on #2310
Jon Ross-Perkins 3 лет назад
Родитель
Сommit
8e5dcc2588

+ 1 - 1
.clang-tidy

@@ -20,7 +20,7 @@ Checks:
   -readability-function-cognitive-complexity, -readability-else-after-return,
   -readability-identifier-length, -readability-implicit-bool-conversion,
   -readability-magic-numbers, -readability-make-member-function-const,
-  -readability-qualified-auto,  -readability-static-definition-in-anonymous-namespace,
+  -readability-static-definition-in-anonymous-namespace,
   -readability-suspicious-call-argument, -readability-use-anyofallof
 WarningsAsErrors: true
 CheckOptions:

+ 1 - 1
explorer/ast/bindings.cpp

@@ -36,7 +36,7 @@ auto Bindings::SymbolicIdentity(
     llvm::ArrayRef<Nonnull<const GenericBinding*>> bindings)
     -> Nonnull<const Bindings*> {
   auto* result = arena->New<Bindings>();
-  for (auto* binding : bindings) {
+  for (const auto* binding : bindings) {
     std::optional<Nonnull<const Value*>> witness;
     if (binding->impl_binding()) {
       witness = *binding->impl_binding().value()->symbolic_identity();

+ 2 - 2
explorer/ast/declaration.h

@@ -285,7 +285,7 @@ class ClassDeclaration : public Declaration {
     return members_;
   }
   auto destructor() const -> std::optional<Nonnull<DestructorDeclaration*>> {
-    for (auto& x : members_) {
+    for (const auto& x : members_) {
       if (x->kind() == DeclarationKind::DestructorDeclaration) {
         return llvm::cast<DestructorDeclaration>(x);
       }
@@ -493,7 +493,7 @@ class InterfaceDeclaration : public Declaration {
         self_type_(arena->New<SelfDeclaration>(source_loc)),
         members_(std::move(members)) {
     // `interface X` has `Self:! X`.
-    auto self_type_ref = arena->New<IdentifierExpression>(source_loc, name);
+    auto* self_type_ref = arena->New<IdentifierExpression>(source_loc, name);
     self_type_ref->set_value_node(self_type_);
     self_ = arena->New<GenericBinding>(source_loc, "Self", self_type_ref);
   }

+ 3 - 3
explorer/ast/expression.cpp

@@ -351,17 +351,17 @@ WhereClause::~WhereClause() = default;
 void WhereClause::Print(llvm::raw_ostream& out) const {
   switch (kind()) {
     case WhereClauseKind::IsWhereClause: {
-      auto& clause = cast<IsWhereClause>(*this);
+      const auto& clause = cast<IsWhereClause>(*this);
       out << clause.type() << " is " << clause.constraint();
       break;
     }
     case WhereClauseKind::EqualsWhereClause: {
-      auto& clause = cast<EqualsWhereClause>(*this);
+      const auto& clause = cast<EqualsWhereClause>(*this);
       out << clause.lhs() << " == " << clause.rhs();
       break;
     }
     case WhereClauseKind::RewriteWhereClause: {
-      auto& clause = cast<RewriteWhereClause>(*this);
+      const auto& clause = cast<RewriteWhereClause>(*this);
       out << "." << clause.member_name() << " = " << clause.replacement();
       break;
     }

+ 1 - 1
explorer/ast/statement.cpp

@@ -25,7 +25,7 @@ void Statement::PrintDepth(int depth, llvm::raw_ostream& out) const {
       out << "match (" << match.expression() << ") {";
       if (depth < 0 || depth > 1) {
         out << "\n";
-        for (auto& clause : match.clauses()) {
+        for (const auto& clause : match.clauses()) {
           out << "case " << clause.pattern() << " =>\n";
           clause.statement().PrintDepth(depth - 1, out);
           out << "\n";

+ 1 - 1
explorer/fuzzing/ast_to_proto.cpp

@@ -495,7 +495,7 @@ static auto StatementToProto(const Statement& statement) -> Fuzzing::Statement {
         // TODO: Working out whether we have a default clause after the fact
         // like this is fragile.
         bool is_default_clause = false;
-        if (auto* binding = dyn_cast<BindingPattern>(&clause.pattern())) {
+        if (const auto* binding = dyn_cast<BindingPattern>(&clause.pattern())) {
           if (binding->name() == AnonymousName &&
               isa<AutoPattern>(binding->type()) &&
               binding->source_loc() == binding->type().source_loc()) {

+ 1 - 1
explorer/interpreter/action.cpp

@@ -143,7 +143,7 @@ void Action::Print(llvm::raw_ostream& out) const {
   if (!results_.empty()) {
     out << " [[";
     llvm::ListSeparator sep;
-    for (auto& result : results_) {
+    for (const auto& result : results_) {
       out << sep << *result;
     }
     out << "]]";

+ 1 - 1
explorer/interpreter/action.h

@@ -71,7 +71,7 @@ class RuntimeScope {
   // Returns the local values in created order
   auto locals() const -> std::vector<Nonnull<const LValue*>> {
     std::vector<Nonnull<const LValue*>> res;
-    for (auto& entry : locals_) {
+    for (const auto& entry : locals_) {
       res.push_back(entry.second);
     }
     return res;

+ 1 - 1
explorer/interpreter/builtins.cpp

@@ -11,7 +11,7 @@ using llvm::dyn_cast;
 namespace Carbon {
 
 void Builtins::Register(Nonnull<const Declaration*> decl) {
-  if (auto* interface = dyn_cast<InterfaceDeclaration>(decl)) {
+  if (const auto* interface = dyn_cast<InterfaceDeclaration>(decl)) {
     static std::map<std::string, int>* builtin_indexes = [] {
       std::map<std::string, int> builtin_indexes;
       for (int index = 0; index <= static_cast<int>(Builtin::Last); ++index) {

+ 2 - 2
explorer/interpreter/exec_program.cpp

@@ -23,7 +23,7 @@ auto AnalyzeProgram(Nonnull<Arena*> arena, AST ast,
     -> ErrorOr<AST> {
   if (trace_stream) {
     **trace_stream << "********** source program **********\n";
-    for (const auto decl : ast.declarations) {
+    for (auto* const decl : ast.declarations) {
       **trace_stream << *decl;
     }
   }
@@ -51,7 +51,7 @@ auto AnalyzeProgram(Nonnull<Arena*> arena, AST ast,
   CARBON_RETURN_IF_ERROR(ResolveUnformed(ast));
   if (trace_stream) {
     **trace_stream << "********** printing declarations **********\n";
-    for (const auto decl : ast.declarations) {
+    for (auto* const decl : ast.declarations) {
       **trace_stream << *decl;
     }
   }

+ 6 - 5
explorer/interpreter/impl_scope.cpp

@@ -26,7 +26,7 @@ void ImplScope::Add(Nonnull<const Value*> iface,
                     llvm::ArrayRef<Nonnull<const ImplBinding*>> impl_bindings,
                     Nonnull<const Witness*> witness,
                     const TypeChecker& type_checker) {
-  if (auto* constraint = dyn_cast<ConstraintType>(iface)) {
+  if (const auto* constraint = dyn_cast<ConstraintType>(iface)) {
     // The caller should have substituted `.Self` for `type` already.
     Add(constraint->impl_constraints(), deduced, impl_bindings, witness,
         type_checker);
@@ -34,7 +34,8 @@ void ImplScope::Add(Nonnull<const Value*> iface,
     // constraints to the scope. Instead, we'll resolve the equality
     // constraints by resolving a witness when needed.
     if (deduced.empty()) {
-      for (auto& equality_constraint : constraint->equality_constraints()) {
+      for (const auto& equality_constraint :
+           constraint->equality_constraints()) {
         equalities_.push_back(&equality_constraint);
       }
     }
@@ -113,7 +114,7 @@ auto ImplScope::Resolve(Nonnull<const Value*> constraint_type,
       Bindings local_bindings = bindings;
       local_bindings.Add(constraint->self_binding(), impl_type, witness);
       SingleStepEqualityContext equality_ctx(this);
-      for (auto& equal : equals) {
+      for (const auto& equal : equals) {
         auto it = equal.values.begin();
         Nonnull<const Value*> first =
             type_checker.Substitute(local_bindings, *it++);
@@ -181,8 +182,8 @@ static auto CombineResults(Nonnull<const InterfaceType*> iface_type,
   }
   // If either of them was a symbolic result, then they'll end up being
   // equivalent. In that case, pick `a`.
-  auto* impl_a = dyn_cast<ImplWitness>(*a);
-  auto* impl_b = dyn_cast<ImplWitness>(*b);
+  const auto* impl_a = dyn_cast<ImplWitness>(*a);
+  const auto* impl_b = dyn_cast<ImplWitness>(*b);
   if (!impl_b) {
     return a;
   }

+ 27 - 25
explorer/interpreter/interpreter.cpp

@@ -192,7 +192,7 @@ void Interpreter::PrintState(llvm::raw_ostream& out) {
   out << "\nmemory: " << heap_;
   out << "\n}\n";
 }
-auto Interpreter::EvalPrim(Operator op, Nonnull<const Value*> static_type,
+auto Interpreter::EvalPrim(Operator op, Nonnull<const Value*> /*static_type*/,
                            const std::vector<Nonnull<const Value*>>& args,
                            SourceLocation source_loc)
     -> ErrorOr<Nonnull<const Value*>> {
@@ -306,7 +306,7 @@ auto PatternMatch(Nonnull<const Value*> p, Nonnull<const Value*> v,
         }
         case Value::Kind::UninitializedValue: {
           const auto& p_tup = cast<TupleValue>(*p);
-          for (auto& ele : p_tup.elements()) {
+          for (const auto& ele : p_tup.elements()) {
             if (!PatternMatch(ele, arena->New<UninitializedValue>(ele),
                               source_loc, bindings, generic_args, trace_stream,
                               arena)) {
@@ -547,7 +547,7 @@ auto Interpreter::EvalAssociatedConstant(
       arena_->New<AssociatedConstant>(base, cast<InterfaceType>(interface),
                                       &assoc->constant(), witness);
 
-  auto* impl_witness = dyn_cast<ImplWitness>(witness);
+  const auto* impl_witness = dyn_cast<ImplWitness>(witness);
   if (!impl_witness) {
     CARBON_CHECK(phase() == Phase::CompileTime)
         << "symbolic witnesses should only be formed at compile time";
@@ -740,7 +740,7 @@ auto Interpreter::Convert(Nonnull<const Value*> value,
     case Value::Kind::StructType: {
       // The value `{}` has kind `StructType` not `StructValue`. This value can
       // be converted to an empty class type.
-      if (auto* destination_class_type =
+      if (const auto* destination_class_type =
               dyn_cast<NominalClassType>(destination_type)) {
         CARBON_CHECK(cast<StructType>(*value).fields().empty())
             << "only an empty struct type value converts to class type";
@@ -1195,7 +1195,8 @@ auto Interpreter::StepExp() -> ErrorOr<Success> {
         } else if ((op.op() == Operator::And || op.op() == Operator::Or) &&
                    act.pos() == 1) {
           // Short-circuit evaluation for 'and' & 'or'
-          auto operand_value = cast<BoolValue>(act.results()[act.pos() - 1]);
+          const auto* operand_value =
+              cast<BoolValue>(act.results()[act.pos() - 1]);
           if ((op.op() == Operator::Or && operand_value->value()) ||
               (op.op() == Operator::And && !operand_value->value())) {
             return todo_.FinishAction(operand_value);
@@ -1323,14 +1324,14 @@ auto Interpreter::StepExp() -> ErrorOr<Success> {
           CARBON_CHECK(args.size() == 2);
           auto lhs = cast<IntValue>(*args[0]).value();
           auto rhs = cast<IntValue>(*args[1]).value();
-          auto result = arena_->New<BoolValue>(lhs == rhs);
+          auto* result = arena_->New<BoolValue>(lhs == rhs);
           return todo_.FinishAction(result);
         }
         case IntrinsicExpression::Intrinsic::StrEq: {
           CARBON_CHECK(args.size() == 2);
-          auto& lhs = cast<StringValue>(*args[0]).value();
-          auto& rhs = cast<StringValue>(*args[1]).value();
-          auto result = arena_->New<BoolValue>(lhs == rhs);
+          const auto& lhs = cast<StringValue>(*args[0]).value();
+          const auto& rhs = cast<StringValue>(*args[1]).value();
+          auto* result = arena_->New<BoolValue>(lhs == rhs);
           return todo_.FinishAction(result);
         }
         case IntrinsicExpression::Intrinsic::IntCompare: {
@@ -1338,29 +1339,29 @@ auto Interpreter::StepExp() -> ErrorOr<Success> {
           auto lhs = cast<IntValue>(*args[0]).value();
           auto rhs = cast<IntValue>(*args[1]).value();
           if (lhs < rhs) {
-            auto result = arena_->New<IntValue>(-1);
+            auto* result = arena_->New<IntValue>(-1);
             return todo_.FinishAction(result);
           }
           if (lhs == rhs) {
-            auto result = arena_->New<IntValue>(0);
+            auto* result = arena_->New<IntValue>(0);
             return todo_.FinishAction(result);
           }
-          auto result = arena_->New<IntValue>(1);
+          auto* result = arena_->New<IntValue>(1);
           return todo_.FinishAction(result);
         }
         case IntrinsicExpression::Intrinsic::StrCompare: {
           CARBON_CHECK(args.size() == 2);
-          auto& lhs = cast<StringValue>(*args[0]).value();
-          auto& rhs = cast<StringValue>(*args[1]).value();
+          const auto& lhs = cast<StringValue>(*args[0]).value();
+          const auto& rhs = cast<StringValue>(*args[1]).value();
           if (lhs < rhs) {
-            auto result = arena_->New<IntValue>(-1);
+            auto* result = arena_->New<IntValue>(-1);
             return todo_.FinishAction(result);
           }
           if (lhs == rhs) {
-            auto result = arena_->New<IntValue>(0);
+            auto* result = arena_->New<IntValue>(0);
             return todo_.FinishAction(result);
           }
-          auto result = arena_->New<IntValue>(1);
+          auto* result = arena_->New<IntValue>(1);
           return todo_.FinishAction(result);
         }
         case IntrinsicExpression::Intrinsic::IntBitComplement: {
@@ -1516,7 +1517,7 @@ auto Interpreter::StepWitness() -> ErrorOr<Success> {
       }
       std::vector<Nonnull<const Witness*>> new_witnesses;
       new_witnesses.reserve(witnesses.size());
-      for (auto* witness : act.results()) {
+      for (const auto* witness : act.results()) {
         new_witnesses.push_back(cast<Witness>(witness));
       }
       return todo_.FinishAction(
@@ -1524,7 +1525,7 @@ auto Interpreter::StepWitness() -> ErrorOr<Success> {
     }
 
     case Value::Kind::ConstraintImplWitness: {
-      auto* constraint_impl = cast<ConstraintImplWitness>(witness);
+      const auto* constraint_impl = cast<ConstraintImplWitness>(witness);
       if (act.pos() == 0) {
         return todo_.Spawn(std::make_unique<WitnessAction>(
             constraint_impl->constraint_witness()));
@@ -1534,7 +1535,7 @@ auto Interpreter::StepWitness() -> ErrorOr<Success> {
     }
 
     case Value::Kind::ImplWitness: {
-      auto* impl_witness = cast<ImplWitness>(witness);
+      const auto* impl_witness = cast<ImplWitness>(witness);
       CARBON_ASSIGN_OR_RETURN(
           Nonnull<const Bindings*> new_bindings,
           InstantiateBindings(&impl_witness->bindings(),
@@ -1724,7 +1725,7 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
               Nonnull<const Value*> assigned_array_element,
               todo_.ValueOfNode(*(loop_var->value_node()), stmt.source_loc()));
 
-          auto lvalue = cast<LValue>(assigned_array_element);
+          const auto* lvalue = cast<LValue>(assigned_array_element);
           CARBON_RETURN_IF_ERROR(heap_.Write(
               lvalue->address(), source_array->elements()[current_index],
               stmt.source_loc()));
@@ -1926,7 +1927,7 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
       const auto& continuation = cast<Continuation>(stmt);
       // Create a continuation object by creating a frame similar the
       // way one is created in a function call.
-      auto fragment = arena_->New<ContinuationValue::StackFragment>();
+      auto* fragment = arena_->New<ContinuationValue::StackFragment>();
       stack_fragments_.push_back(fragment);
       todo_.InitializeFragment(*fragment, &continuation.body());
       // Bind the continuation object to the continuation variable
@@ -1935,7 +1936,7 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
       return todo_.FinishAction();
     }
     case StatementKind::Run: {
-      auto& run = cast<Run>(stmt);
+      const auto& run = cast<Run>(stmt);
       if (act.pos() == 0) {
         // Evaluate the argument of the run statement.
         return todo_.Spawn(std::make_unique<ExpressionAction>(&run.argument()));
@@ -2005,7 +2006,8 @@ auto Interpreter::StepCleanUp() -> ErrorOr<Success> {
   Action& act = todo_.CurrentAction();
   auto& cleanup = cast<CleanupAction>(act);
   if (act.pos() < cleanup.locals_count()) {
-    auto lvalue = act.scope()->locals()[cleanup.locals_count() - act.pos() - 1];
+    const auto* lvalue =
+        act.scope()->locals()[cleanup.locals_count() - act.pos() - 1];
     SourceLocation source_loc("destructor", 1);
     auto value = heap_.Read(lvalue->address(), source_loc);
     if (value.ok()) {
@@ -2026,7 +2028,7 @@ auto Interpreter::StepCleanUp() -> ErrorOr<Success> {
             if (const auto* var = dyn_cast<VariableDeclaration>(member)) {
               const auto& type = var->static_type();
               if (const auto* c_type = dyn_cast<NominalClassType>(&type)) {
-                auto& c_dec = c_type->declaration();
+                const auto& c_dec = c_type->declaration();
                 if (c_dec.destructor().has_value()) {
                   Address object = lvalue->address();
                   Address mem = object.SubobjectAddress(Member(var));

+ 26 - 25
explorer/interpreter/pattern_analysis.cpp

@@ -13,10 +13,10 @@ using llvm::isa;
 namespace Carbon {
 
 auto AbstractPattern::kind() const -> Kind {
-  if (auto* pattern = value_.dyn_cast<const Pattern*>()) {
+  if (const auto* pattern = value_.dyn_cast<const Pattern*>()) {
     return Compound;
   }
-  if (auto* value = value_.dyn_cast<const Value*>()) {
+  if (const auto* value = value_.dyn_cast<const Value*>()) {
     if (isa<TupleValue, AlternativeValue, BoolValue>(value)) {
       return Compound;
     }
@@ -28,14 +28,14 @@ auto AbstractPattern::kind() const -> Kind {
 
 auto AbstractPattern::discriminator() const -> std::string_view {
   CARBON_CHECK(kind() == Compound);
-  if (auto* pattern = value_.dyn_cast<const Pattern*>()) {
-    if (auto* alt_pattern = dyn_cast<AlternativePattern>(pattern)) {
+  if (const auto* pattern = value_.dyn_cast<const Pattern*>()) {
+    if (const auto* alt_pattern = dyn_cast<AlternativePattern>(pattern)) {
       return alt_pattern->alternative_name();
     }
-  } else if (auto* value = value_.dyn_cast<const Value*>()) {
-    if (auto* alt = dyn_cast<AlternativeValue>(value)) {
+  } else if (const auto* value = value_.dyn_cast<const Value*>()) {
+    if (const auto* alt = dyn_cast<AlternativeValue>(value)) {
       return alt->alt_name();
-    } else if (auto* bool_val = dyn_cast<BoolValue>(value)) {
+    } else if (const auto* bool_val = dyn_cast<BoolValue>(value)) {
       return bool_val->value() ? "true" : "false";
     }
   }
@@ -43,16 +43,16 @@ auto AbstractPattern::discriminator() const -> std::string_view {
 }
 
 auto AbstractPattern::elements_size() const -> int {
-  if (auto* pattern = value_.dyn_cast<const Pattern*>()) {
-    if (auto* tuple_pattern = dyn_cast<TuplePattern>(pattern)) {
+  if (const auto* pattern = value_.dyn_cast<const Pattern*>()) {
+    if (const auto* tuple_pattern = dyn_cast<TuplePattern>(pattern)) {
       return tuple_pattern->fields().size();
     } else if (isa<AlternativePattern>(pattern)) {
       return 1;
     }
-  } else if (auto* value = value_.dyn_cast<const Value*>()) {
-    if (auto* tuple = dyn_cast<TupleValue>(value)) {
+  } else if (const auto* value = value_.dyn_cast<const Value*>()) {
+    if (const auto* tuple = dyn_cast<TupleValue>(value)) {
       return tuple->elements().size();
-    } else if (auto* alt = dyn_cast<AlternativeValue>(value)) {
+    } else if (const auto* alt = dyn_cast<AlternativeValue>(value)) {
       return 1;
     }
   }
@@ -61,22 +61,23 @@ auto AbstractPattern::elements_size() const -> int {
 
 void AbstractPattern::AppendElementsTo(
     std::vector<AbstractPattern>& out) const {
-  if (auto* pattern = value_.dyn_cast<const Pattern*>()) {
-    if (auto* tuple_pattern = dyn_cast<TuplePattern>(pattern)) {
+  if (const auto* pattern = value_.dyn_cast<const Pattern*>()) {
+    if (const auto* tuple_pattern = dyn_cast<TuplePattern>(pattern)) {
       auto fields = tuple_pattern->fields();
       out.insert(out.end(), fields.begin(), fields.end());
-    } else if (auto* alt_pattern = dyn_cast<AlternativePattern>(pattern)) {
+    } else if (const auto* alt_pattern =
+                   dyn_cast<AlternativePattern>(pattern)) {
       out.push_back(&alt_pattern->arguments());
     }
-  } else if (auto* value = value_.dyn_cast<const Value*>()) {
-    if (auto* tuple = dyn_cast<TupleValue>(value)) {
-      auto* tuple_type = cast<TupleValue>(type_);
+  } else if (const auto* value = value_.dyn_cast<const Value*>()) {
+    if (const auto* tuple = dyn_cast<TupleValue>(value)) {
+      const auto* tuple_type = cast<TupleValue>(type_);
       CARBON_CHECK(tuple->elements().size() == tuple_type->elements().size());
       for (size_t i = 0; i != tuple->elements().size(); ++i) {
         out.push_back(
             AbstractPattern(tuple->elements()[i], tuple_type->elements()[i]));
       }
-    } else if (auto* alt = dyn_cast<AlternativeValue>(value)) {
+    } else if (const auto* alt = dyn_cast<AlternativeValue>(value)) {
       out.push_back(AbstractPattern(
           &alt->argument(),
           *cast<ChoiceType>(type_)->FindAlternative(alt->alt_name())));
@@ -172,21 +173,21 @@ auto PatternMatrix::FirstColumnDiscriminators() const -> DiscriminatorSet {
   std::optional<int> num_discrims;
   std::optional<int> elem_size;
 
-  for (auto& row : matrix_) {
+  for (const auto& row : matrix_) {
     CARBON_CHECK(!row.empty());
     switch (row[0].kind()) {
       case AbstractPattern::Wildcard:
         continue;
       case AbstractPattern::Compound: {
         const Value& type = row[0].type();
-        if (auto* tuple = dyn_cast<TupleValue>(&type)) {
+        if (const auto* tuple = dyn_cast<TupleValue>(&type)) {
           // If we find a tuple match, we've found all constructors (there's
           // only one!) and none were missing.
           return {
               .found = {{.discriminator = {},
                          .size = static_cast<int>(tuple->elements().size())}},
               .any_missing = false};
-        } else if (auto* choice = dyn_cast<ChoiceType>(&type)) {
+        } else if (const auto* choice = dyn_cast<ChoiceType>(&type)) {
           num_discrims = choice->declaration().alternatives().size();
           elem_size = 1;
         } else if (isa<BoolType>(type)) {
@@ -252,7 +253,7 @@ auto PatternMatrix::SpecializeRow(llvm::ArrayRef<AbstractPattern> row,
 auto PatternMatrix::Specialize(DiscriminatorInfo discriminator) const
     -> PatternMatrix {
   PatternMatrix specialized;
-  for (auto& row : matrix_) {
+  for (const auto& row : matrix_) {
     // TODO: If we add support for "or" patterns, specialization might
     // produce multiple rows here.
     if (auto new_row = SpecializeRow(row, discriminator)) {
@@ -266,7 +267,7 @@ auto PatternMatrix::Specialize(DiscriminatorInfo discriminator) const
 // to be `value`, and is not matched.
 auto PatternMatrix::Specialize(const Value& value) const -> PatternMatrix {
   PatternMatrix specialized;
-  for (auto& row : matrix_) {
+  for (const auto& row : matrix_) {
     CARBON_CHECK(!row.empty());
     switch (row[0].kind()) {
       case AbstractPattern::Wildcard:
@@ -289,7 +290,7 @@ auto PatternMatrix::Specialize(const Value& value) const -> PatternMatrix {
 // discriminator matching none of the non-wildcard patterns.
 auto PatternMatrix::Default() const -> PatternMatrix {
   PatternMatrix default_matrix;
-  for (auto& row : matrix_) {
+  for (const auto& row : matrix_) {
     CARBON_CHECK(!row.empty());
     switch (row[0].kind()) {
       case AbstractPattern::Wildcard:

+ 1 - 1
explorer/interpreter/resolve_control_flow.cpp

@@ -192,7 +192,7 @@ auto ResolveControlFlow(Nonnull<Declaration*> declaration) -> ErrorOr<Success> {
 }
 
 auto ResolveControlFlow(AST& ast) -> ErrorOr<Success> {
-  for (auto declaration : ast.declarations) {
+  for (auto* declaration : ast.declarations) {
     CARBON_RETURN_IF_ERROR(ResolveControlFlow(declaration));
   }
   return Success();

+ 12 - 12
explorer/interpreter/resolve_names.cpp

@@ -23,7 +23,7 @@ static auto AddExposedNames(const Declaration& declaration,
                             StaticScope& enclosing_scope) -> ErrorOr<Success> {
   switch (declaration.kind()) {
     case DeclarationKind::InterfaceDeclaration: {
-      auto& iface_decl = cast<InterfaceDeclaration>(declaration);
+      const auto& iface_decl = cast<InterfaceDeclaration>(declaration);
       CARBON_RETURN_IF_ERROR(
           enclosing_scope.Add(iface_decl.name(), &iface_decl,
                               StaticScope::NameStatus::KnownButNotDeclared));
@@ -33,40 +33,40 @@ static auto AddExposedNames(const Declaration& declaration,
       // TODO: Remove this code. With this code, it is possible to create not
       // useful carbon code.
       //       Without this code, a Segfault is generated
-      auto& func = cast<DestructorDeclaration>(declaration);
+      const auto& func = cast<DestructorDeclaration>(declaration);
       CARBON_RETURN_IF_ERROR(enclosing_scope.Add(
           "destructor", &func, StaticScope::NameStatus::KnownButNotDeclared));
       break;
     }
     case DeclarationKind::FunctionDeclaration: {
-      auto& func = cast<FunctionDeclaration>(declaration);
+      const auto& func = cast<FunctionDeclaration>(declaration);
       CARBON_RETURN_IF_ERROR(enclosing_scope.Add(
           func.name(), &func, StaticScope::NameStatus::KnownButNotDeclared));
       break;
     }
     case DeclarationKind::ClassDeclaration: {
-      auto& class_decl = cast<ClassDeclaration>(declaration);
+      const auto& class_decl = cast<ClassDeclaration>(declaration);
       CARBON_RETURN_IF_ERROR(
           enclosing_scope.Add(class_decl.name(), &class_decl,
                               StaticScope::NameStatus::KnownButNotDeclared));
       break;
     }
     case DeclarationKind::MixinDeclaration: {
-      auto& mixin_decl = cast<MixinDeclaration>(declaration);
+      const auto& mixin_decl = cast<MixinDeclaration>(declaration);
       CARBON_RETURN_IF_ERROR(
           enclosing_scope.Add(mixin_decl.name(), &mixin_decl,
                               StaticScope::NameStatus::KnownButNotDeclared));
       break;
     }
     case DeclarationKind::ChoiceDeclaration: {
-      auto& choice = cast<ChoiceDeclaration>(declaration);
+      const auto& choice = cast<ChoiceDeclaration>(declaration);
       CARBON_RETURN_IF_ERROR(
           enclosing_scope.Add(choice.name(), &choice,
                               StaticScope::NameStatus::KnownButNotDeclared));
       break;
     }
     case DeclarationKind::VariableDeclaration: {
-      auto& var = cast<VariableDeclaration>(declaration);
+      const auto& var = cast<VariableDeclaration>(declaration);
       if (var.binding().name() != AnonymousName) {
         CARBON_RETURN_IF_ERROR(
             enclosing_scope.Add(var.binding().name(), &var.binding(),
@@ -75,7 +75,7 @@ static auto AddExposedNames(const Declaration& declaration,
       break;
     }
     case DeclarationKind::AssociatedConstantDeclaration: {
-      auto& let = cast<AssociatedConstantDeclaration>(declaration);
+      const auto& let = cast<AssociatedConstantDeclaration>(declaration);
       if (let.binding().name() != AnonymousName) {
         CARBON_RETURN_IF_ERROR(
             enclosing_scope.Add(let.binding().name(), &let.binding()));
@@ -83,12 +83,12 @@ static auto AddExposedNames(const Declaration& declaration,
       break;
     }
     case DeclarationKind::SelfDeclaration: {
-      auto& self = cast<SelfDeclaration>(declaration);
+      const auto& self = cast<SelfDeclaration>(declaration);
       CARBON_RETURN_IF_ERROR(enclosing_scope.Add("Self", &self));
       break;
     }
     case DeclarationKind::AliasDeclaration: {
-      auto& alias = cast<AliasDeclaration>(declaration);
+      const auto& alias = cast<AliasDeclaration>(declaration);
       CARBON_RETURN_IF_ERROR(enclosing_scope.Add(
           alias.name(), &alias, StaticScope::NameStatus::KnownButNotDeclared));
       break;
@@ -675,10 +675,10 @@ static auto ResolveNames(Declaration& declaration, StaticScope& enclosing_scope,
 
 auto ResolveNames(AST& ast) -> ErrorOr<Success> {
   StaticScope file_scope;
-  for (auto declaration : ast.declarations) {
+  for (auto* declaration : ast.declarations) {
     CARBON_RETURN_IF_ERROR(AddExposedNames(*declaration, file_scope));
   }
-  for (auto declaration : ast.declarations) {
+  for (auto* declaration : ast.declarations) {
     CARBON_RETURN_IF_ERROR(ResolveNames(
         *declaration, file_scope, ResolveFunctionBodies::AfterDeclarations));
   }

+ 19 - 18
explorer/interpreter/resolve_unformed.cpp

@@ -73,14 +73,14 @@ static auto ResolveUnformed(Nonnull<const Expression*> expression,
     -> ErrorOr<Success> {
   switch (expression->kind()) {
     case ExpressionKind::IdentifierExpression: {
-      auto& identifier = cast<IdentifierExpression>(*expression);
+      const auto& identifier = cast<IdentifierExpression>(*expression);
       CARBON_RETURN_IF_ERROR(
           flow_facts.TakeAction(&identifier.value_node().base(), action,
                                 identifier.source_loc(), identifier.name()));
       break;
     }
     case ExpressionKind::CallExpression: {
-      auto& call = cast<CallExpression>(*expression);
+      const auto& call = cast<CallExpression>(*expression);
       CARBON_RETURN_IF_ERROR(
           ResolveUnformed(&call.argument(), flow_facts, action));
       break;
@@ -92,7 +92,7 @@ static auto ResolveUnformed(Nonnull<const Expression*> expression,
       }
       break;
     case ExpressionKind::OperatorExpression: {
-      auto& opt_exp = cast<OperatorExpression>(*expression);
+      const auto& opt_exp = cast<OperatorExpression>(*expression);
       if (opt_exp.op() == Operator::AddressOf) {
         CARBON_CHECK(opt_exp.arguments().size() == 1)
             << "OperatorExpression with op & can only have 1 argument";
@@ -150,7 +150,7 @@ static auto ResolveUnformed(Nonnull<const Pattern*> pattern,
     -> ErrorOr<Success> {
   switch (pattern->kind()) {
     case PatternKind::BindingPattern: {
-      auto& binding_pattern = cast<BindingPattern>(*pattern);
+      const auto& binding_pattern = cast<BindingPattern>(*pattern);
       CARBON_RETURN_IF_ERROR(flow_facts.TakeAction(&binding_pattern, action,
                                                    binding_pattern.source_loc(),
                                                    binding_pattern.name()));
@@ -178,15 +178,15 @@ static auto ResolveUnformed(Nonnull<const Statement*> statement,
     -> ErrorOr<Success> {
   switch (statement->kind()) {
     case StatementKind::Block: {
-      auto& block = cast<Block>(*statement);
-      for (auto* block_statement : block.statements()) {
+      const auto& block = cast<Block>(*statement);
+      for (const auto* block_statement : block.statements()) {
         CARBON_RETURN_IF_ERROR(
             ResolveUnformed(block_statement, flow_facts, action));
       }
       break;
     }
     case StatementKind::VariableDefinition: {
-      auto& def = cast<VariableDefinition>(*statement);
+      const auto& def = cast<VariableDefinition>(*statement);
       if (def.has_init()) {
         CARBON_RETURN_IF_ERROR(ResolveUnformed(&def.pattern(), flow_facts,
                                                FlowFacts::ActionType::AddInit));
@@ -199,22 +199,23 @@ static auto ResolveUnformed(Nonnull<const Statement*> statement,
       break;
     }
     case StatementKind::ReturnVar: {
-      auto& ret_var = cast<ReturnVar>(*statement);
-      auto& binding_pattern = cast<BindingPattern>(ret_var.value_node().base());
+      const auto& ret_var = cast<ReturnVar>(*statement);
+      const auto& binding_pattern =
+          cast<BindingPattern>(ret_var.value_node().base());
       CARBON_RETURN_IF_ERROR(
           flow_facts.TakeAction(&binding_pattern, FlowFacts::ActionType::Check,
                                 ret_var.source_loc(), binding_pattern.name()));
       break;
     }
     case StatementKind::ReturnExpression: {
-      auto& ret_exp_stmt = cast<ReturnExpression>(*statement);
+      const auto& ret_exp_stmt = cast<ReturnExpression>(*statement);
       CARBON_RETURN_IF_ERROR(ResolveUnformed(&ret_exp_stmt.expression(),
                                              flow_facts,
                                              FlowFacts::ActionType::Check));
       break;
     }
     case StatementKind::Assign: {
-      auto& assign = cast<Assign>(*statement);
+      const auto& assign = cast<Assign>(*statement);
       if (assign.lhs().kind() == ExpressionKind::IdentifierExpression) {
         CARBON_RETURN_IF_ERROR(ResolveUnformed(&assign.lhs(), flow_facts,
                                                FlowFacts::ActionType::Form));
@@ -228,13 +229,13 @@ static auto ResolveUnformed(Nonnull<const Statement*> statement,
       break;
     }
     case StatementKind::ExpressionStatement: {
-      auto& exp_stmt = cast<ExpressionStatement>(*statement);
+      const auto& exp_stmt = cast<ExpressionStatement>(*statement);
       CARBON_RETURN_IF_ERROR(
           ResolveUnformed(&exp_stmt.expression(), flow_facts, action));
       break;
     }
     case StatementKind::If: {
-      auto& if_stmt = cast<If>(*statement);
+      const auto& if_stmt = cast<If>(*statement);
       CARBON_RETURN_IF_ERROR(ResolveUnformed(&if_stmt.condition(), flow_facts,
                                              FlowFacts::ActionType::Check));
       CARBON_RETURN_IF_ERROR(
@@ -246,7 +247,7 @@ static auto ResolveUnformed(Nonnull<const Statement*> statement,
       break;
     }
     case StatementKind::While: {
-      auto& while_stmt = cast<While>(*statement);
+      const auto& while_stmt = cast<While>(*statement);
       CARBON_RETURN_IF_ERROR(ResolveUnformed(
           &while_stmt.condition(), flow_facts, FlowFacts::ActionType::Check));
       CARBON_RETURN_IF_ERROR(
@@ -254,10 +255,10 @@ static auto ResolveUnformed(Nonnull<const Statement*> statement,
       break;
     }
     case StatementKind::Match: {
-      auto& match = cast<Match>(*statement);
+      const auto& match = cast<Match>(*statement);
       CARBON_RETURN_IF_ERROR(ResolveUnformed(&match.expression(), flow_facts,
                                              FlowFacts::ActionType::Check));
-      for (auto& clause : match.clauses()) {
+      for (const auto& clause : match.clauses()) {
         CARBON_RETURN_IF_ERROR(ResolveUnformed(&clause.pattern(), flow_facts,
                                                FlowFacts::ActionType::Check));
         CARBON_RETURN_IF_ERROR(
@@ -285,7 +286,7 @@ static auto ResolveUnformed(Nonnull<const Declaration*> declaration)
     // available.
     case DeclarationKind::FunctionDeclaration:
     case DeclarationKind::DestructorDeclaration: {
-      auto& callable = cast<CallableDeclaration>(*declaration);
+      const auto& callable = cast<CallableDeclaration>(*declaration);
       if (callable.body().has_value()) {
         FlowFacts flow_facts;
         CARBON_RETURN_IF_ERROR(ResolveUnformed(*callable.body(), flow_facts,
@@ -312,7 +313,7 @@ static auto ResolveUnformed(Nonnull<const Declaration*> declaration)
 }
 
 auto ResolveUnformed(const AST& ast) -> ErrorOr<Success> {
-  for (auto declaration : ast.declarations) {
+  for (auto* declaration : ast.declarations) {
     CARBON_RETURN_IF_ERROR(ResolveUnformed(declaration));
   }
   return Success();

+ 46 - 41
explorer/interpreter/type_checker.cpp

@@ -331,7 +331,7 @@ auto TypeChecker::ExpectIsConcreteType(SourceLocation source_loc,
 static auto FindField(llvm::ArrayRef<NamedValue> fields,
                       const std::string& field_name)
     -> std::optional<NamedValue> {
-  auto it = std::find_if(
+  const auto* it = std::find_if(
       fields.begin(), fields.end(),
       [&](const NamedValue& field) { return field.name == field_name; });
   if (it == fields.end()) {
@@ -555,7 +555,7 @@ auto TypeChecker::GetBuiltinInterfaceType(SourceLocation source_loc,
   // Find the builtin interface declaration.
   CARBON_ASSIGN_OR_RETURN(Nonnull<const Declaration*> builtin_decl,
                           builtins_.Get(source_loc, interface.builtin));
-  auto* iface_decl = dyn_cast<InterfaceDeclaration>(builtin_decl);
+  const auto* iface_decl = dyn_cast<InterfaceDeclaration>(builtin_decl);
   if (!iface_decl || !iface_decl->constant_value()) {
     return bad_builtin();
   }
@@ -639,12 +639,12 @@ class TypeChecker::ArgumentDeduction {
     if (trace_stream_) {
       **trace_stream_ << "performing argument deduction for bindings: ";
       llvm::ListSeparator sep;
-      for (auto* binding : bindings_to_deduce) {
+      for (const auto* binding : bindings_to_deduce) {
         **trace_stream_ << sep << *binding;
       }
       **trace_stream_ << "\n";
     }
-    for (auto* binding : bindings_to_deduce) {
+    for (const auto* binding : bindings_to_deduce) {
       deduced_values_.insert({binding, {}});
     }
   }
@@ -658,7 +658,7 @@ class TypeChecker::ArgumentDeduction {
   // Finds a binding to deduce that has not been deduced, if any exist.
   auto FindUndeducedBinding() const
       -> std::optional<Nonnull<const GenericBinding*>> {
-    for (auto* binding : deduced_bindings_in_order_) {
+    for (const auto* binding : deduced_bindings_in_order_) {
       llvm::ArrayRef<Nonnull<const Value*>> values =
           deduced_values_.find(binding)->second;
       if (values.empty()) {
@@ -947,7 +947,7 @@ auto TypeChecker::ArgumentDeduction::Finish(TypeChecker& type_checker,
   // declaration order so that any bindings used in the type of a later binding
   // have known values before we check that binding.
   Bindings bindings;
-  for (auto* binding : deduced_bindings_in_order_) {
+  for (const auto* binding : deduced_bindings_in_order_) {
     llvm::ArrayRef<Nonnull<const Value*>> values =
         deduced_values_.find(binding)->second;
     if (values.empty()) {
@@ -960,8 +960,8 @@ auto TypeChecker::ArgumentDeduction::Finish(TypeChecker& type_checker,
         type_checker.Substitute(bindings, &binding->static_type());
     const Value* substituted_type =
         type_checker.Substitute(bindings, binding_type);
-    auto* first_value = values[0];
-    for (auto* value : values) {
+    const auto* first_value = values[0];
+    for (const auto* value : values) {
       // TODO: It's not clear that conversions are or should be possible here.
       // If they are permitted, we should allow user-defined conversions, and
       // actually perform the conversion.
@@ -1033,7 +1033,7 @@ auto TypeChecker::ArgumentDeduction::Finish(TypeChecker& type_checker,
   }
 
   // Check non-deduced potential mismatches now we can substitute into them.
-  for (auto& mismatch : non_deduced_mismatches_) {
+  for (const auto& mismatch : non_deduced_mismatches_) {
     const Value* subst_param_type =
         type_checker.Substitute(bindings, mismatch.param);
     CARBON_RETURN_IF_ERROR(
@@ -1193,7 +1193,7 @@ class TypeChecker::ConstraintTypeBuilder {
     // TODO: What happens if these rewrites appear in the impl constraints?
     // TODO: What happens if these rewrites appear in each other?
     for (const auto& rewrite_constraint : constraint->rewrite_constraints()) {
-      auto* interface = cast<InterfaceType>(type_checker.Substitute(
+      const auto* interface = cast<InterfaceType>(type_checker.Substitute(
           local_bindings, rewrite_constraint.interface));
       Nonnull<const Value*> value = type_checker.Substitute(
           local_bindings, &rewrite_constraint.replacement->value());
@@ -1266,7 +1266,8 @@ class TypeChecker::ConstraintTypeBuilder {
       bool performed_rewrite;
       do {
         performed_rewrite = false;
-        if (auto* assoc = dyn_cast<AssociatedConstant>(impl_constraint.type);
+        if (const auto* assoc =
+                dyn_cast<AssociatedConstant>(impl_constraint.type);
             assoc && ValueEqual(&assoc->base(), GetSelfType(), std::nullopt)) {
           for (const auto& rewrite : rewrite_constraints_) {
             if (&assoc->constant() == rewrite.constant &&
@@ -1461,7 +1462,7 @@ auto TypeChecker::Substitute(const Bindings& bindings,
     case Value::Kind::StructType: {
       std::vector<NamedValue> fields;
       for (const auto& [name, value] : cast<StructType>(*type).fields()) {
-        auto new_type = Substitute(bindings, value);
+        const auto* new_type = Substitute(bindings, value);
         fields.push_back({name, new_type});
       }
       return arena_->New<StructType>(std::move(fields));
@@ -1487,8 +1488,10 @@ auto TypeChecker::Substitute(const Bindings& bindings,
 
       // Apply substitution to parameter and return types and create the new
       // function type.
-      auto param = Substitute(subst_bindings.bindings(), &fn_type.parameters());
-      auto ret = Substitute(subst_bindings.bindings(), &fn_type.return_type());
+      const auto* param =
+          Substitute(subst_bindings.bindings(), &fn_type.parameters());
+      const auto* ret =
+          Substitute(subst_bindings.bindings(), &fn_type.return_type());
       return arena_->New<FunctionType>(
           param, std::move(generic_parameters), ret,
           std::move(deduced_bindings),
@@ -1521,9 +1524,9 @@ auto TypeChecker::Substitute(const Bindings& bindings,
         // function that takes a `T:! Constraint` parameter. In this case we
         // produce the new type-of-type of the replacement type.
         Nonnull<const Value*> type_of_type;
-        if (auto* var_type = dyn_cast<VariableType>(it->second)) {
+        if (const auto* var_type = dyn_cast<VariableType>(it->second)) {
           type_of_type = &var_type->binding().static_type();
-        } else if (auto* assoc_type =
+        } else if (const auto* assoc_type =
                        dyn_cast<AssociatedConstant>(it->second)) {
           type_of_type = GetTypeForAssociatedConstant(assoc_type);
         } else {
@@ -1579,7 +1582,7 @@ auto TypeChecker::Substitute(const Bindings& bindings,
       const auto& witness = cast<ConstraintWitness>(*type);
       std::vector<Nonnull<const Witness*>> witnesses;
       witnesses.reserve(witness.witnesses().size());
-      for (auto* witness : witness.witnesses()) {
+      for (const auto* witness : witness.witnesses()) {
         witnesses.push_back(cast<Witness>(Substitute(bindings, witness)));
       }
       return arena_->New<ConstraintWitness>(std::move(witnesses));
@@ -1895,7 +1898,7 @@ static auto LookupRewrite(Nonnull<const Value*> type_of_type,
 
 auto TypeChecker::GetTypeForAssociatedConstant(
     Nonnull<const AssociatedConstant*> assoc) const -> Nonnull<const Value*> {
-  auto* assoc_type = &assoc->constant().static_type();
+  const auto* assoc_type = &assoc->constant().static_type();
   Bindings bindings = assoc->interface().bindings();
   bindings.Add(assoc->interface().declaration().self(), &assoc->base(),
                &assoc->witness());
@@ -1907,7 +1910,7 @@ auto TypeChecker::LookupRewriteInTypeOf(
     Nonnull<const Declaration*> member) const
     -> std::optional<const ValueLiteral*> {
   // Given `(T:! C).Y`, look in `C` for rewrites.
-  if (auto* var_type = dyn_cast<VariableType>(type)) {
+  if (const auto* var_type = dyn_cast<VariableType>(type)) {
     if (!var_type->binding().has_static_type()) {
       // We looked for a rewrite before we finished type-checking the generic
       // binding. This happens when forming the type of a generic binding. Just
@@ -1920,7 +1923,7 @@ auto TypeChecker::LookupRewriteInTypeOf(
   // Given `(T.U).Y` for an associated type `U`, substitute into the type of
   // `U` to find rewrites.
   // TODO: This substitution can lead to infinite recursion.
-  if (auto* assoc_const = dyn_cast<AssociatedConstant>(type)) {
+  if (const auto* assoc_const = dyn_cast<AssociatedConstant>(type)) {
     return LookupRewrite(GetTypeForAssociatedConstant(assoc_const), interface,
                          member);
   }
@@ -1932,7 +1935,7 @@ auto TypeChecker::LookupRewriteInWitness(
     Nonnull<const Witness*> witness, Nonnull<const InterfaceType*> interface,
     Nonnull<const Declaration*> member) const
     -> std::optional<const ValueLiteral*> {
-  if (auto* impl_witness = dyn_cast<ImplWitness>(witness)) {
+  if (const auto* impl_witness = dyn_cast<ImplWitness>(witness)) {
     Nonnull<const Value*> constraint =
         Substitute(impl_witness->bindings(),
                    impl_witness->declaration().constraint_type());
@@ -2103,7 +2106,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
                 access.set_value_category(access.object().value_category());
                 break;
               case DeclarationKind::FunctionDeclaration: {
-                auto func_decl = cast<FunctionDeclaration>(member);
+                const auto* func_decl = cast<FunctionDeclaration>(member);
                 if (func_decl->is_method() && func_decl->me_pattern().kind() ==
                                                   PatternKind::AddrPattern) {
                   access.set_is_field_addr_me_method();
@@ -2143,7 +2146,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
           // the return type of `y()` is an associated constant from `T`'s
           // constraint.
           Nonnull<const Value*> constraint;
-          if (auto* var_type = dyn_cast<VariableType>(&object_type)) {
+          if (const auto* var_type = dyn_cast<VariableType>(&object_type)) {
             constraint = &var_type->binding().static_type();
           } else {
             constraint = GetTypeForAssociatedConstant(
@@ -2446,7 +2449,8 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
           bindings.Add(iface_type->declaration().self(), *base_type, witness);
           return Substitute(bindings, member_type);
         }
-        if (auto* class_type = dyn_cast<NominalClassType>(base_type.value())) {
+        if (const auto* class_type =
+                dyn_cast<NominalClassType>(base_type.value())) {
           return Substitute(class_type->bindings(), member_type);
         }
         return member_type;
@@ -2779,7 +2783,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
               param_name.params().fields();
           for (size_t i = 0; i != params.size(); ++i) {
             // TODO: Should we disallow all other kinds of top-level params?
-            if (auto* binding = dyn_cast<GenericBinding>(params[i])) {
+            if (const auto* binding = dyn_cast<GenericBinding>(params[i])) {
               generic_parameters.push_back({i, binding});
             }
           }
@@ -2863,7 +2867,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
             return ProgramError(e->source_loc())
                    << "__intrinsic_new takes 1 argument";
           }
-          auto arg_type = &args[0]->static_type();
+          const auto* arg_type = &args[0]->static_type();
           e->set_static_type(arena_->New<PointerType>(arg_type));
           e->set_value_category(ValueCategory::Let);
           return Success();
@@ -2873,7 +2877,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
             return ProgramError(e->source_loc())
                    << "__intrinsic_new takes 1 argument";
           }
-          auto arg_type = &args[0]->static_type();
+          const auto* arg_type = &args[0]->static_type();
           CARBON_RETURN_IF_ERROR(
               ExpectPointerType(e->source_loc(), "*", arg_type));
           e->set_static_type(TupleValue::Empty());
@@ -3126,7 +3130,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
             // Also find (or add) `.Self is I`, and add `.Self.T == V`.
             int index = builder.AddImplConstraint(
                 {.type = builder.GetSelfType(), .interface = result.interface});
-            auto* witness =
+            const auto* witness =
                 MakeConstraintWitnessAccess(builder.GetSelfWitness(), index);
             builder.AddEqualityConstraint(
                 {.values = {arena_->New<AssociatedConstant>(
@@ -3174,7 +3178,7 @@ void TypeChecker::CollectGenericBindingsInPattern(
     Nonnull<const Pattern*> p,
     std::vector<Nonnull<const GenericBinding*>>& generic_bindings) {
   VisitNestedPatterns(*p, [&](const Pattern& pattern) {
-    if (auto* binding = dyn_cast<GenericBinding>(&pattern)) {
+    if (const auto* binding = dyn_cast<GenericBinding>(&pattern)) {
       generic_bindings.push_back(binding);
     }
     return true;
@@ -3185,7 +3189,7 @@ void TypeChecker::CollectImplBindingsInPattern(
     Nonnull<const Pattern*> p,
     std::vector<Nonnull<const ImplBinding*>>& impl_bindings) {
   VisitNestedPatterns(*p, [&](const Pattern& pattern) {
-    if (auto* binding = dyn_cast<GenericBinding>(&pattern)) {
+    if (const auto* binding = dyn_cast<GenericBinding>(&pattern)) {
       if (binding->impl_binding().has_value()) {
         impl_bindings.push_back(binding->impl_binding().value());
       }
@@ -3484,7 +3488,7 @@ auto TypeChecker::TypeCheckPattern(
                                               expected_ptr, impl_scope,
                                               enclosing_value_category));
 
-      if (auto* inner_binding_type =
+      if (const auto* inner_binding_type =
               dyn_cast<PointerType>(&addr_pattern.binding().static_type())) {
         addr_pattern.set_static_type(&inner_binding_type->type());
       } else {
@@ -3831,7 +3835,7 @@ auto TypeChecker::DeclareCallableDeclaration(Nonnull<CallableDeclaration*> f,
   std::vector<FunctionType::GenericParameter> generic_parameters;
   for (size_t i = 0; i != f->param_pattern().fields().size(); ++i) {
     const Pattern* param_pattern = f->param_pattern().fields()[i];
-    if (auto* binding = dyn_cast<GenericBinding>(param_pattern)) {
+    if (const auto* binding = dyn_cast<GenericBinding>(param_pattern)) {
       generic_parameters.push_back({i, binding});
     } else {
       CollectGenericBindingsInPattern(param_pattern, deduced_bindings);
@@ -4133,7 +4137,7 @@ auto TypeChecker::TypeCheckMixDeclaration(
 
   CARBON_CHECK(enclosing_decl.has_value());
   Nonnull<const Declaration*> encl_decl = enclosing_decl.value();
-  auto& mixin_decl = mix_decl->mixin_value().declaration();
+  const auto& mixin_decl = mix_decl->mixin_value().declaration();
   CARBON_RETURN_IF_ERROR(TypeCheckMixinDeclaration(&mixin_decl, impl_scope));
   CollectedMembersMap& mix_members = FindCollectedMembers(&mixin_decl);
 
@@ -4204,7 +4208,7 @@ auto TypeChecker::DeclareInterfaceDeclaration(
   int index = builder.AddImplConstraint(
       {.type = builder.GetSelfType(), .interface = iface_type});
   builder.AddLookupContext({.context = iface_type});
-  auto* impl_witness =
+  const auto* impl_witness =
       MakeConstraintWitnessAccess(builder.GetSelfWitness(), index);
 
   ScopeInfo iface_scope_info = ScopeInfo::ForNonClassScope(&iface_scope);
@@ -4391,7 +4395,7 @@ auto TypeChecker::CheckAndAddImplBindings(
   // either those impls or impls available elsewhere.
   Nonnull<const ConstraintType*> constraint = impl_decl->constraint_type();
   for (auto lookup : constraint->lookup_contexts()) {
-    if (auto* iface_type = dyn_cast<InterfaceType>(lookup.context)) {
+    if (const auto* iface_type = dyn_cast<InterfaceType>(lookup.context)) {
       CARBON_RETURN_IF_ERROR(ExpectCompleteType(
           impl_decl->source_loc(), "impl declaration", iface_type));
       CARBON_RETURN_IF_ERROR(
@@ -4511,13 +4515,13 @@ auto TypeChecker::DeclareImplDeclaration(Nonnull<ImplDeclaration*> impl_decl,
     // For each interface we're going to implement, this impl is the witness
     // that that interface is implemented.
     for (auto lookup : constraint_type->lookup_contexts()) {
-      if (auto* iface_type = dyn_cast<InterfaceType>(lookup.context)) {
+      if (const auto* iface_type = dyn_cast<InterfaceType>(lookup.context)) {
         self_impl_scope.Add(iface_type, impl_type_value, self_witness, *this);
       }
     }
     // This impl also provides all of its equalities.
     // TODO: Only the ones from rewrite constraints.
-    for (auto& eq : constraint_type->equality_constraints()) {
+    for (const auto& eq : constraint_type->equality_constraints()) {
       self_impl_scope.AddEqualityConstraint(&eq);
     }
     // Ensure that's enough for our interface to be satisfied.
@@ -4557,7 +4561,7 @@ void TypeChecker::BringAssociatedConstantsIntoScope(
 
   for (const auto& eq : constraint->equality_constraints()) {
     for (Nonnull<const Value*> value : eq.values) {
-      if (auto* assoc = dyn_cast<AssociatedConstant>(value)) {
+      if (const auto* assoc = dyn_cast<AssociatedConstant>(value)) {
         if (assocs_in_interface.count(&assoc->constant()) &&
             ValueEqual(&assoc->base(), self, std::nullopt) &&
             ValueEqual(&assoc->interface(), interface, std::nullopt)) {
@@ -4639,7 +4643,7 @@ auto TypeChecker::DeclareChoiceDeclaration(Nonnull<ChoiceDeclaration*> choice,
     return Success();
   }
 
-  auto ct = arena_->New<ChoiceType>(
+  auto* ct = arena_->New<ChoiceType>(
       choice, Bindings::SymbolicIdentity(arena_, bindings));
 
   choice->set_static_type(arena_->New<TypeType>());
@@ -4869,7 +4873,7 @@ auto TypeChecker::DeclareDeclaration(Nonnull<Declaration*> d,
           Nonnull<const Value*> mixin,
           InterpExp(&mix_decl.mixin(), arena_, trace_stream_));
       mix_decl.set_mixin_value(cast<MixinPseudoType>(mixin));
-      auto& mixin_decl = mix_decl.mixin_value().declaration();
+      const auto& mixin_decl = mix_decl.mixin_value().declaration();
       if (!mixin_decl.is_declared()) {
         return ProgramError(mix_decl.source_loc())
                << "incomplete mixin `" << mixin_decl.name()
@@ -4959,7 +4963,8 @@ auto TypeChecker::FindMixedMemberAndType(
           // TODO: What is the type of Self? Do we ever need a witness?
           temp_map.Add(mixin->declaration().self(), enclosing_type,
                        std::nullopt);
-          const auto mix_member_type = Substitute(temp_map, res.value().first);
+          const auto* const mix_member_type =
+              Substitute(temp_map, res.value().first);
           return {std::make_pair(mix_member_type, res.value().second)};
         } else {
           return res;

+ 10 - 9
explorer/interpreter/value.cpp

@@ -38,11 +38,12 @@ static auto GetMember(Nonnull<Arena*> arena, Nonnull<const Value*> v,
   std::string_view f = field.name();
 
   if (field.witness().has_value()) {
-    auto witness = cast<Witness>(*field.witness());
+    const auto* witness = cast<Witness>(*field.witness());
 
     // Associated constants.
-    if (auto* assoc_const = dyn_cast_or_null<AssociatedConstantDeclaration>(
-            field.member().declaration().value_or(nullptr))) {
+    if (const auto* assoc_const =
+            dyn_cast_or_null<AssociatedConstantDeclaration>(
+                field.member().declaration().value_or(nullptr))) {
       CARBON_CHECK(field.interface()) << "have witness but no interface";
       // TODO: Use witness to find the value of the constant.
       return arena->New<AssociatedConstant>(v, *field.interface(), assoc_const,
@@ -50,7 +51,7 @@ static auto GetMember(Nonnull<Arena*> arena, Nonnull<const Value*> v,
     }
 
     // Associated functions.
-    if (auto* impl_witness = dyn_cast<ImplWitness>(witness)) {
+    if (const auto* impl_witness = dyn_cast<ImplWitness>(witness)) {
       if (std::optional<Nonnull<const Declaration*>> mem_decl =
               FindMember(f, impl_witness->declaration().members());
           mem_decl.has_value()) {
@@ -60,7 +61,7 @@ static auto GetMember(Nonnull<Arena*> arena, Nonnull<const Value*> v,
                                               &impl_witness->bindings());
         } else {
           // Class function.
-          auto* fun = cast<FunctionValue>(*fun_decl.constant_value());
+          const auto* fun = cast<FunctionValue>(*fun_decl.constant_value());
           return arena->New<FunctionValue>(&fun->declaration(),
                                            &impl_witness->bindings());
         }
@@ -88,7 +89,7 @@ static auto GetMember(Nonnull<Arena*> arena, Nonnull<const Value*> v,
       // Note that the value representation of an empty class is a
       // `StructType`, not a `StructValue`.
       std::optional<Nonnull<const Value*>> field;
-      if (auto* struct_value = dyn_cast<StructValue>(&object.inits())) {
+      if (const auto* struct_value = dyn_cast<StructValue>(&object.inits())) {
         field = struct_value->FindField(f);
       }
       if (field.has_value()) {
@@ -469,7 +470,7 @@ void Value::Print(llvm::raw_ostream& out) const {
       const auto& witness = cast<ConstraintWitness>(*this);
       out << "(";
       llvm::ListSeparator sep;
-      for (auto* elem : witness.witnesses()) {
+      for (const auto* elem : witness.witnesses()) {
         out << sep << *elem;
       }
       out << ")";
@@ -940,7 +941,7 @@ auto EqualityConstraint::VisitEqualValues(
 
   // The value is in this group; pass all non-identical values in the group
   // to the visitor. First visit the values we already compared.
-  for (auto* val : llvm::make_range(values.begin(), first_equal)) {
+  for (const auto* val : llvm::make_range(values.begin(), first_equal)) {
     if (!visitor(val)) {
       return false;
     }
@@ -948,7 +949,7 @@ auto EqualityConstraint::VisitEqualValues(
   // Then visit any remaining non-identical values, skipping the one we already
   // found was identical.
   ++first_equal;
-  for (auto* val : llvm::make_range(first_equal, values.end())) {
+  for (const auto* val : llvm::make_range(first_equal, values.end())) {
     if (!ValueEqual(value, val, std::nullopt) && !visitor(val)) {
       return false;
     }

+ 2 - 1
explorer/interpreter/value.h

@@ -932,7 +932,8 @@ class ConstraintImplWitness : public Witness {
                    int index) -> Nonnull<const Witness*> {
     CARBON_CHECK(!llvm::isa<ImplWitness>(witness))
         << "impl witness has no components to access";
-    if (auto* constraint_witness = llvm::dyn_cast<ConstraintWitness>(witness)) {
+    if (const auto* constraint_witness =
+            llvm::dyn_cast<ConstraintWitness>(witness)) {
       return constraint_witness->witnesses()[index];
     }
     return arena->New<ConstraintImplWitness>(witness, index);

+ 2 - 2
explorer/syntax/parse.cpp

@@ -54,7 +54,7 @@ auto Parse(Nonnull<Arena*> arena, std::string_view input_file_name,
   // Prepare the lexer.
   yyscan_t scanner;
   yylex_init(&scanner);
-  auto buffer = yy_create_buffer(input_file, YY_BUF_SIZE, scanner);
+  auto* buffer = yy_create_buffer(input_file, YY_BUF_SIZE, scanner);
   yy_switch_to_buffer(buffer, scanner);
 
   ErrorOr<AST> result =
@@ -74,7 +74,7 @@ auto ParseFromString(Nonnull<Arena*> arena, std::string_view input_file_name,
   // Prepare the lexer.
   yyscan_t scanner;
   yylex_init(&scanner);
-  auto buffer =
+  auto* buffer =
       yy_scan_bytes(file_contents.data(), file_contents.size(), scanner);
   yy_switch_to_buffer(buffer, scanner);
 

+ 2 - 2
toolchain/common/yaml_test_helpers.cpp

@@ -79,7 +79,7 @@ auto operator<<(std::ostream& os, const Value& v) -> std::ostream& {
     auto operator()(const MappingValue& v) -> void {
       out << "Yaml::MappingValue{";
       bool first = true;
-      for (auto& [key, value] : v) {
+      for (const auto& [key, value] : v) {
         if (first) {
           first = false;
         } else {
@@ -92,7 +92,7 @@ auto operator<<(std::ostream& os, const Value& v) -> std::ostream& {
     auto operator()(const SequenceValue& v) -> void {
       out << "Yaml::SequenceValue{";
       bool first = true;
-      for (auto& value : v) {
+      for (const auto& value : v) {
         if (first) {
           first = false;
         } else {

+ 2 - 2
toolchain/driver/driver.cpp

@@ -85,12 +85,12 @@ auto Driver::RunHelpSubcommand(DiagnosticConsumer& /*consumer*/,
   };
 
   int max_subcommand_width = 0;
-  for (auto subcommand_and_help : SubcommandsAndHelp) {
+  for (const auto* subcommand_and_help : SubcommandsAndHelp) {
     max_subcommand_width = std::max(
         max_subcommand_width, static_cast<int>(subcommand_and_help[0].size()));
   }
 
-  for (auto subcommand_and_help : SubcommandsAndHelp) {
+  for (const auto* subcommand_and_help : SubcommandsAndHelp) {
     llvm::StringRef subcommand_text = subcommand_and_help[0];
     // TODO: We should wrap this to the number of columns left after the
     // subcommand on the terminal, and using a hanging indent.

+ 1 - 1
toolchain/lexer/numeric_literal.cpp

@@ -360,7 +360,7 @@ auto LexedNumericLiteral::Parser::CheckDigitSeparatorPlacement(
   // groups of 3 or 4 digits (4 or 5 characters), respectively.
   int stride = (radix == Radix::Decimal ? 4 : 5);
   int remaining_digit_separators = num_digit_separators;
-  auto pos = text.end();
+  const auto* pos = text.end();
   while (pos - text.begin() >= stride) {
     pos -= stride;
     if (*pos != '_') {

+ 15 - 15
toolchain/lexer/tokenized_buffer.cpp

@@ -603,14 +603,14 @@ auto TokenizedBuffer::GetColumnNumber(Token token) const -> int {
 }
 
 auto TokenizedBuffer::GetTokenText(Token token) const -> llvm::StringRef {
-  auto& token_info = GetTokenInfo(token);
+  const auto& token_info = GetTokenInfo(token);
   llvm::StringRef fixed_spelling = token_info.kind.GetFixedSpelling();
   if (!fixed_spelling.empty()) {
     return fixed_spelling;
   }
 
   if (token_info.kind == TokenKind::Error()) {
-    auto& line_info = GetLineInfo(token_info.token_line);
+    const auto& line_info = GetLineInfo(token_info.token_line);
     int64_t token_start = line_info.start + token_info.column;
     return source_->text().substr(token_start, token_info.error_length);
   }
@@ -619,7 +619,7 @@ auto TokenizedBuffer::GetTokenText(Token token) const -> llvm::StringRef {
   // separators the author included.
   if (token_info.kind == TokenKind::IntegerLiteral() ||
       token_info.kind == TokenKind::RealLiteral()) {
-    auto& line_info = GetLineInfo(token_info.token_line);
+    const auto& line_info = GetLineInfo(token_info.token_line);
     int64_t token_start = line_info.start + token_info.column;
     llvm::Optional<LexedNumericLiteral> relexed_token =
         LexedNumericLiteral::Lex(source_->text().substr(token_start));
@@ -630,7 +630,7 @@ auto TokenizedBuffer::GetTokenText(Token token) const -> llvm::StringRef {
   // Refer back to the source text to find the original spelling, including
   // escape sequences etc.
   if (token_info.kind == TokenKind::StringLiteral()) {
-    auto& line_info = GetLineInfo(token_info.token_line);
+    const auto& line_info = GetLineInfo(token_info.token_line);
     int64_t token_start = line_info.start + token_info.column;
     llvm::Optional<LexedStringLiteral> relexed_token =
         LexedStringLiteral::Lex(source_->text().substr(token_start));
@@ -641,7 +641,7 @@ auto TokenizedBuffer::GetTokenText(Token token) const -> llvm::StringRef {
   // Refer back to the source text to avoid needing to reconstruct the
   // spelling from the size.
   if (token_info.kind.IsSizedTypeLiteral()) {
-    auto& line_info = GetLineInfo(token_info.token_line);
+    const auto& line_info = GetLineInfo(token_info.token_line);
     int64_t token_start = line_info.start + token_info.column;
     llvm::StringRef suffix =
         source_->text().substr(token_start + 1).take_while(IsDecimalDigit);
@@ -658,7 +658,7 @@ auto TokenizedBuffer::GetTokenText(Token token) const -> llvm::StringRef {
 }
 
 auto TokenizedBuffer::GetIdentifier(Token token) const -> Identifier {
-  auto& token_info = GetTokenInfo(token);
+  const auto& token_info = GetTokenInfo(token);
   CARBON_CHECK(token_info.kind == TokenKind::Identifier())
       << "The token must be an identifier!";
   return token_info.id;
@@ -666,21 +666,21 @@ auto TokenizedBuffer::GetIdentifier(Token token) const -> Identifier {
 
 auto TokenizedBuffer::GetIntegerLiteral(Token token) const
     -> const llvm::APInt& {
-  auto& token_info = GetTokenInfo(token);
+  const auto& token_info = GetTokenInfo(token);
   CARBON_CHECK(token_info.kind == TokenKind::IntegerLiteral())
       << "The token must be an integer literal!";
   return literal_int_storage_[token_info.literal_index];
 }
 
 auto TokenizedBuffer::GetRealLiteral(Token token) const -> RealLiteralValue {
-  auto& token_info = GetTokenInfo(token);
+  const auto& token_info = GetTokenInfo(token);
   CARBON_CHECK(token_info.kind == TokenKind::RealLiteral())
       << "The token must be a real literal!";
 
   // Note that every real literal is at least three characters long, so we can
   // safely look at the second character to determine whether we have a
   // decimal or hexadecimal literal.
-  auto& line_info = GetLineInfo(token_info.token_line);
+  const auto& line_info = GetLineInfo(token_info.token_line);
   int64_t token_start = line_info.start + token_info.column;
   char second_char = source_->text()[token_start + 1];
   bool is_decimal = second_char != 'x' && second_char != 'b';
@@ -689,7 +689,7 @@ auto TokenizedBuffer::GetRealLiteral(Token token) const -> RealLiteralValue {
 }
 
 auto TokenizedBuffer::GetStringLiteral(Token token) const -> llvm::StringRef {
-  auto& token_info = GetTokenInfo(token);
+  const auto& token_info = GetTokenInfo(token);
   CARBON_CHECK(token_info.kind == TokenKind::StringLiteral())
       << "The token must be a string literal!";
   return literal_string_storage_[token_info.literal_index];
@@ -697,7 +697,7 @@ auto TokenizedBuffer::GetStringLiteral(Token token) const -> llvm::StringRef {
 
 auto TokenizedBuffer::GetTypeLiteralSize(Token token) const
     -> const llvm::APInt& {
-  auto& token_info = GetTokenInfo(token);
+  const auto& token_info = GetTokenInfo(token);
   CARBON_CHECK(token_info.kind.IsSizedTypeLiteral())
       << "The token must be a sized type literal!";
   return literal_int_storage_[token_info.literal_index];
@@ -705,7 +705,7 @@ auto TokenizedBuffer::GetTypeLiteralSize(Token token) const
 
 auto TokenizedBuffer::GetMatchedClosingToken(Token opening_token) const
     -> Token {
-  auto& opening_token_info = GetTokenInfo(opening_token);
+  const auto& opening_token_info = GetTokenInfo(opening_token);
   CARBON_CHECK(opening_token_info.kind.IsOpeningSymbol())
       << "The token must be an opening group symbol!";
   return opening_token_info.closing_token;
@@ -713,7 +713,7 @@ auto TokenizedBuffer::GetMatchedClosingToken(Token opening_token) const
 
 auto TokenizedBuffer::GetMatchedOpeningToken(Token closing_token) const
     -> Token {
-  auto& closing_token_info = GetTokenInfo(closing_token);
+  const auto& closing_token_info = GetTokenInfo(closing_token);
   CARBON_CHECK(closing_token_info.kind.IsClosingSymbol())
       << "The token must be an closing group symbol!";
   return closing_token_info.opening_token;
@@ -804,7 +804,7 @@ auto TokenizedBuffer::PrintToken(llvm::raw_ostream& output_stream, Token token,
                                  PrintWidths widths) const -> void {
   widths.Widen(GetTokenPrintWidths(token));
   int token_index = token.index_;
-  auto& token_info = GetTokenInfo(token);
+  const auto& token_info = GetTokenInfo(token);
   llvm::StringRef token_text = GetTokenText(token);
 
   // Output the main chunk using one format string. We have to do the
@@ -899,7 +899,7 @@ auto TokenizedBuffer::SourceBufferLocationTranslator::GetLocation(
   // Find the first line starting after the given location. Note that we can't
   // inspect `line.length` here because it is not necessarily correct for the
   // final line during lexing (but will be correct later for the parse tree).
-  auto line_it = std::partition_point(
+  auto* line_it = std::partition_point(
       buffer_->line_infos_.begin(), buffer_->line_infos_.end(),
       [offset](const LineInfo& line) { return line.start <= offset; });
   bool incomplete_line_info = last_line_lexed_to_column_ != nullptr &&

+ 3 - 3
toolchain/parser/parse_tree.cpp

@@ -104,7 +104,7 @@ auto ParseTree::Print(llvm::raw_ostream& output) const -> void {
     Node n;
     int depth;
     std::tie(n, depth) = node_stack.pop_back_val();
-    auto& n_impl = node_impls_[n.index()];
+    const auto& n_impl = node_impls_[n.index()];
 
     for (int unused_indent : llvm::seq(0, depth)) {
       (void)unused_indent;
@@ -153,7 +153,7 @@ auto ParseTree::Verify() const -> bool {
   // Verify basic tree structure invariants.
   llvm::SmallVector<ParseTree::Node, 16> ancestors;
   for (Node n : llvm::reverse(postorder())) {
-    auto& n_impl = node_impls_[n.index()];
+    const auto& n_impl = node_impls_[n.index()];
 
     if (n_impl.has_error && !has_errors_) {
       llvm::errs()
@@ -165,7 +165,7 @@ auto ParseTree::Verify() const -> bool {
     if (n_impl.subtree_size > 1) {
       if (!ancestors.empty()) {
         auto parent_n = ancestors.back();
-        auto& parent_n_impl = node_impls_[parent_n.index()];
+        const auto& parent_n_impl = node_impls_[parent_n.index()];
         int end_index = n.index() - n_impl.subtree_size;
         int parent_end_index = parent_n.index() - parent_n_impl.subtree_size;
         if (parent_end_index > end_index) {