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

Finish making clang-tidy (mostly) work (again) and run -fix (#2312)

This does some more work to the run_clang_tidy.py wrapper script, and runs an example pass.

"again" because it's really the proto fuzzer changes that broke it, it had been working before.

"mostly" because there's still an issue within the proto fuzzer that it can't find "port/protobuf.h", i.e. https://github.com/google/libprotobuf-mutator/tree/master/port, but I'm still hesitant to add an include path there.
Jon Ross-Perkins 3 лет назад
Родитель
Сommit
4d522c8e90

+ 1 - 1
common/indirect_value_test.cpp

@@ -58,7 +58,7 @@ struct TestValue {
   TestValue(TestValue&& other) noexcept : state("move constructed") {
     other.state = "move constructed from";
   }
-  auto operator=(const TestValue&) noexcept -> TestValue& {
+  auto operator=(const TestValue& /*unused*/) noexcept -> TestValue& {
     state = "copy assigned";
     return *this;
   }

+ 0 - 1
common/string_helpers_test.cpp

@@ -11,7 +11,6 @@
 
 #include "llvm/Support/Error.h"
 
-using ::llvm::toString;
 using ::testing::Eq;
 using ::testing::Optional;
 

+ 8 - 0
compile_flags.txt

@@ -98,6 +98,14 @@ bazel-bin/external/com_google_googletest/googletest
 bazel-execroot/external/com_google_googletest/googletest/include
 -isystem
 bazel-bin/external/com_google_googletest/googletest/include
+-isystem
+bazel-execroot/external/com_google_libprotobuf_mutator/src
+-isystem
+bazel-bin/external/com_google_libprotobuf_mutator/src
+-isystem
+bazel-execroot/external/com_github_protocolbuffers_protobuf/src
+-isystem
+bazel-bin/external/com_github_protocolbuffers_protobuf/src
 -std=c++17
 -stdlib=libc++
 -no-canonical-prefixes

+ 5 - 3
explorer/ast/bindings.h

@@ -6,6 +6,7 @@
 #define CARBON_EXPLORER_AST_BINDINGS_H_
 
 #include <map>
+#include <utility>
 
 #include "explorer/common/nonnull.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -40,18 +41,19 @@ class Bindings {
       -> Nonnull<const Bindings*>;
 
   // Create an empty set of bindings.
-  Bindings() {}
+  Bindings() = default;
 
   // Create an instantiated set of bindings for use during evaluation,
   // containing both arguments and witnesses.
   Bindings(BindingMap args, ImplWitnessMap witnesses)
-      : args_(args), witnesses_(witnesses) {}
+      : args_(std::move(args)), witnesses_(std::move(witnesses)) {}
 
   enum NoWitnessesTag { NoWitnesses };
 
   // Create a set of bindings for use during type-checking, containing only the
   // arguments but not the corresponding witnesses.
-  Bindings(BindingMap args, NoWitnessesTag) : args_(args), witnesses_() {}
+  Bindings(BindingMap args, NoWitnessesTag /*unused*/)
+      : args_(std::move(args)) {}
 
   // Add a value, and perhaps a witness, for a generic binding.
   void Add(Nonnull<const GenericBinding*> binding, Nonnull<const Value*> value,

+ 4 - 4
explorer/ast/declaration.h

@@ -316,7 +316,7 @@ class MixinDeclaration : public Declaration {
                    std::vector<Nonnull<Declaration*>> members)
       : Declaration(AstNodeKind::MixinDeclaration, source_loc),
         name_(std::move(name)),
-        params_(std::move(params)),
+        params_(params),
         self_(self),
         members_(std::move(members)) {}
 
@@ -489,7 +489,7 @@ class InterfaceDeclaration : public Declaration {
                        std::vector<Nonnull<Declaration*>> members)
       : Declaration(AstNodeKind::InterfaceDeclaration, source_loc),
         name_(std::move(name)),
-        params_(std::move(params)),
+        params_(params),
         self_type_(arena->New<SelfDeclaration>(source_loc)),
         members_(std::move(members)) {
     // `interface X` has `Self:! X`.
@@ -688,10 +688,10 @@ class AliasDeclaration : public Declaration {
  public:
   using ImplementsCarbonValueNode = void;
 
-  explicit AliasDeclaration(SourceLocation source_loc, const std::string& name,
+  explicit AliasDeclaration(SourceLocation source_loc, std::string name,
                             Nonnull<Expression*> target)
       : Declaration(AstNodeKind::AliasDeclaration, source_loc),
-        name_(name),
+        name_(std::move(name)),
         target_(target) {}
 
   static auto classof(const AstNode* node) -> bool {

+ 2 - 1
explorer/ast/expression.h

@@ -8,6 +8,7 @@
 #include <map>
 #include <optional>
 #include <string>
+#include <utility>
 #include <variant>
 #include <vector>
 
@@ -876,7 +877,7 @@ class RewriteWhereClause : public WhereClause {
                               std::string member_name,
                               Nonnull<Expression*> replacement)
       : WhereClause(WhereClauseKind::RewriteWhereClause, source_loc),
-        member_name_(member_name),
+        member_name_(std::move(member_name)),
         replacement_(replacement) {}
 
   static auto classof(const AstNode* node) {

+ 3 - 2
explorer/ast/impl_binding.h

@@ -80,10 +80,11 @@ class ImplBinding : public AstNode {
 
   // Return the original impl binding.
   auto original() const -> Nonnull<const ImplBinding*> {
-    if (original_.has_value())
+    if (original_.has_value()) {
       return *original_;
-    else
+    } else {
       return this;
+    }
   }
 
   // Set the original impl binding.

+ 3 - 3
explorer/ast/member.cpp

@@ -15,7 +15,7 @@ Member::Member(Nonnull<const NamedValue*> struct_member)
     : member_(struct_member) {}
 
 auto Member::name() const -> std::string_view {
-  if (const Declaration* decl = member_.dyn_cast<const Declaration*>()) {
+  if (const auto* decl = member_.dyn_cast<const Declaration*>()) {
     return GetName(*decl).value();
   } else {
     return member_.get<const NamedValue*>()->name;
@@ -23,7 +23,7 @@ auto Member::name() const -> std::string_view {
 }
 
 auto Member::type() const -> const Value& {
-  if (const Declaration* decl = member_.dyn_cast<const Declaration*>()) {
+  if (const auto* decl = member_.dyn_cast<const Declaration*>()) {
     return decl->static_type();
   } else {
     return *member_.get<const NamedValue*>()->value;
@@ -31,7 +31,7 @@ auto Member::type() const -> const Value& {
 }
 
 auto Member::declaration() const -> std::optional<Nonnull<const Declaration*>> {
-  if (const Declaration* decl = member_.dyn_cast<const Declaration*>()) {
+  if (const auto* decl = member_.dyn_cast<const Declaration*>()) {
     return decl;
   }
   return std::nullopt;

+ 3 - 2
explorer/ast/pattern.h

@@ -275,10 +275,11 @@ class GenericBinding : public Pattern {
 
   // Return the original generic binding.
   auto original() const -> Nonnull<const GenericBinding*> {
-    if (original_.has_value())
+    if (original_.has_value()) {
       return *original_;
-    else
+    } else {
       return this;
+    }
   }
   // Set the original generic binding.
   void set_original(Nonnull<const GenericBinding*> orig) { original_ = orig; }

+ 1 - 1
explorer/fuzzing/ast_to_proto.cpp

@@ -772,7 +772,7 @@ static auto DeclarationToProto(const Declaration& declaration)
   return declaration_proto;
 }
 
-Fuzzing::CompilationUnit AstToProto(const AST& ast) {
+auto AstToProto(const AST& ast) -> Fuzzing::CompilationUnit {
   Fuzzing::CompilationUnit compilation_unit;
   *compilation_unit.mutable_package_statement() =
       LibraryNameToProto(ast.package);

+ 1 - 1
explorer/fuzzing/ast_to_proto_test.cpp

@@ -121,7 +121,7 @@ TEST(AstToProtoTest, SetsAllProtoFields) {
 }  // namespace
 }  // namespace Carbon::Testing
 
-int main(int argc, char** argv) {
+auto main(int argc, char** argv) -> int {
   ::testing::InitGoogleTest(&argc, argv);
   // gtest should remove flags, leaving just input files.
   Carbon::Testing::carbon_files =

+ 1 - 1
explorer/fuzzing/explorer_fuzzer.cpp

@@ -2,7 +2,7 @@
 // Exceptions. See /LICENSE for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
-#include <libprotobuf_mutator/src/libfuzzer/libfuzzer_macro.h>
+#include <libfuzzer/libfuzzer_macro.h>
 
 #include "common/error.h"
 #include "explorer/fuzzing/fuzzer_util.h"

+ 1 - 1
explorer/interpreter/action_stack.h

@@ -90,7 +90,7 @@ class ActionStack {
       -> ErrorOr<Success>;
   // Replace the current action with another action that produces the same kind
   // of result and run it next.
-  auto ReplaceWith(std::unique_ptr<Action> child) -> ErrorOr<Success>;
+  auto ReplaceWith(std::unique_ptr<Action> replacement) -> ErrorOr<Success>;
 
   // Start a new recursive action.
   auto BeginRecursiveAction() {

+ 1 - 1
explorer/interpreter/builtins.h

@@ -20,7 +20,7 @@ namespace Carbon {
 
 class Builtins {
  public:
-  explicit Builtins() {}
+  explicit Builtins() = default;
 
   enum class Builtin {
     // Conversions.

+ 0 - 1
explorer/interpreter/impl_scope.cpp

@@ -11,7 +11,6 @@
 
 using llvm::cast;
 using llvm::dyn_cast;
-using llvm::isa;
 
 namespace Carbon {
 

+ 1 - 1
explorer/interpreter/impl_scope.h

@@ -158,7 +158,7 @@ class ImplScope {
 // scope.
 struct SingleStepEqualityContext : public EqualityContext {
  public:
-  SingleStepEqualityContext(Nonnull<const ImplScope*> impl_scope)
+  explicit SingleStepEqualityContext(Nonnull<const ImplScope*> impl_scope)
       : impl_scope_(impl_scope) {}
 
   // Visits the values that are equal to the given value and a single step away

+ 20 - 20
explorer/interpreter/interpreter.cpp

@@ -160,7 +160,7 @@ class Interpreter {
 
   void PrintState(llvm::raw_ostream& out);
 
-  Phase phase() const { return phase_; }
+  auto phase() const -> Phase { return phase_; }
 
   Nonnull<Arena*> arena_;
 
@@ -830,7 +830,7 @@ auto Interpreter::CallFunction(const CallExpression& call,
           alt.alt_name(), alt.choice_name(), arg));
     }
     case Value::Kind::FunctionValue: {
-      const FunctionValue& fun_val = cast<FunctionValue>(*fun);
+      const auto& fun_val = cast<FunctionValue>(*fun);
       const FunctionDeclaration& function = fun_val.declaration();
       if (!function.body().has_value()) {
         return ProgramError(call.source_loc())
@@ -1213,7 +1213,7 @@ auto Interpreter::StepExp() -> ErrorOr<Success> {
       }
     }
     case ExpressionKind::CallExpression: {
-      const CallExpression& call = cast<CallExpression>(exp);
+      const auto& call = cast<CallExpression>(exp);
       unsigned int num_impls = call.impls().size();
       if (act.pos() == 0) {
         //    { {e1(e2) :: C, E, F} :: S, H}
@@ -1225,12 +1225,12 @@ auto Interpreter::StepExp() -> ErrorOr<Success> {
         // -> { { e :: v([]) :: C, E, F} :: S, H}
         return todo_.Spawn(
             std::make_unique<ExpressionAction>(&call.argument()));
-      } else if (num_impls > 0 && act.pos() < 2 + int(num_impls)) {
+      } else if (num_impls > 0 && act.pos() < 2 + static_cast<int>(num_impls)) {
         auto iter = call.impls().begin();
         std::advance(iter, act.pos() - 2);
         return todo_.Spawn(
             std::make_unique<WitnessAction>(cast<Witness>(iter->second)));
-      } else if (act.pos() == 2 + int(num_impls)) {
+      } else if (act.pos() == 2 + static_cast<int>(num_impls)) {
         //    { { v2 :: v1([]) :: C, E, F} :: S, H}
         // -> { {C',E',F'} :: {C, E, F} :: S, H}
         ImplWitnessMap witnesses;
@@ -1243,12 +1243,13 @@ auto Interpreter::StepExp() -> ErrorOr<Success> {
         }
         return CallFunction(call, act.results()[0], act.results()[1],
                             std::move(witnesses));
-      } else if (act.pos() == 3 + int(num_impls)) {
+      } else if (act.pos() == 3 + static_cast<int>(num_impls)) {
         if (act.results().size() < 3 + num_impls) {
           // Control fell through without explicit return.
           return todo_.FinishAction(TupleValue::Empty());
         } else {
-          return todo_.FinishAction(act.results()[2 + int(num_impls)]);
+          return todo_.FinishAction(
+              act.results()[2 + static_cast<int>(num_impls)]);
         }
       } else {
         CARBON_FATAL() << "in StepExp with Call pos " << act.pos();
@@ -1292,7 +1293,8 @@ auto Interpreter::StepExp() -> ErrorOr<Success> {
           CARBON_ASSIGN_OR_RETURN(
               Nonnull<const Value*> string_value,
               Convert(args[1], arena_->New<StringType>(), exp.source_loc()));
-          if (cast<BoolValue>(condition)->value() == false) {
+          bool condition_value = cast<BoolValue>(condition)->value();
+          if (!condition_value) {
             return ProgramError(exp.source_loc()) << *string_value;
           }
           return todo_.FinishAction(TupleValue::Empty());
@@ -1679,8 +1681,8 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
             std::make_unique<ExpressionAction>(&cast<For>(stmt).loop_target()));
       }
       if (act.pos() == 1) {
-        Nonnull<const TupleValue*> source_array =
-            cast<const TupleValue>(act.results()[TargetVarPosInResult]);
+        const auto* source_array =
+            cast<TupleValue>(act.results()[TargetVarPosInResult]);
 
         auto end_index = static_cast<int>(source_array->elements().size());
         if (end_index == 0) {
@@ -1692,11 +1694,10 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
             &cast<For>(stmt).variable_declaration()));
       }
       if (act.pos() == 2) {
-        Nonnull<const BindingPlaceholderValue*> loop_var =
-            cast<const BindingPlaceholderValue>(
-                act.results()[LoopVarPosInResult]);
-        Nonnull<const TupleValue*> source_array =
-            cast<const TupleValue>(act.results()[TargetVarPosInResult]);
+        const auto* loop_var =
+            cast<BindingPlaceholderValue>(act.results()[LoopVarPosInResult]);
+        const auto* source_array =
+            cast<TupleValue>(act.results()[TargetVarPosInResult]);
 
         auto start_index =
             cast<IntValue>(act.results()[CurrentIndexPosInResult])->value();
@@ -1714,11 +1715,10 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
             cast<IntValue>(act.results()[EndIndexPosInResult])->value();
 
         if (current_index < end_index) {
-          Nonnull<const TupleValue*> source_array =
+          const auto* source_array =
               cast<const TupleValue>(act.results()[TargetVarPosInResult]);
-          Nonnull<const BindingPlaceholderValue*> loop_var =
-              cast<const BindingPlaceholderValue>(
-                  act.results()[LoopVarPosInResult]);
+          const auto* loop_var = cast<const BindingPlaceholderValue>(
+              act.results()[LoopVarPosInResult]);
 
           CARBON_ASSIGN_OR_RETURN(
               Nonnull<const Value*> assigned_array_element,
@@ -2003,7 +2003,7 @@ auto Interpreter::StepDeclaration() -> ErrorOr<Success> {
 
 auto Interpreter::StepCleanUp() -> ErrorOr<Success> {
   Action& act = todo_.CurrentAction();
-  CleanupAction& cleanup = cast<CleanupAction>(act);
+  auto& cleanup = cast<CleanupAction>(act);
   if (act.pos() < cleanup.locals_count()) {
     auto lvalue = act.scope()->locals()[cleanup.locals_count() - act.pos() - 1];
     SourceLocation source_loc("destructor", 1);

+ 1 - 1
explorer/interpreter/pattern_analysis.h

@@ -65,7 +65,7 @@ class AbstractPattern {
  private:
   // This is aligned so that we can use it in the `PointerUnion` below.
   struct alignas(8) WildcardTag {};
-  AbstractPattern(WildcardTag)
+  explicit AbstractPattern(WildcardTag /*unused*/)
       : value_(static_cast<const WildcardTag*>(nullptr)), type_(nullptr) {}
 
   void Set(Nonnull<const Pattern*> pattern);

+ 26 - 26
explorer/interpreter/type_checker.cpp

@@ -27,7 +27,6 @@
 
 using llvm::cast;
 using llvm::dyn_cast;
-using llvm::dyn_cast_or_null;
 using llvm::isa;
 
 namespace Carbon {
@@ -44,7 +43,7 @@ static void SetValue(Nonnull<Pattern*> pattern, Nonnull<const Value*> value) {
 
 auto TypeChecker::IsSameType(Nonnull<const Value*> type1,
                              Nonnull<const Value*> type2,
-                             const ImplScope& impl_scope) const -> bool {
+                             const ImplScope& /*impl_scope*/) const -> bool {
   return TypeEqual(type1, type2, std::nullopt);
 }
 
@@ -1076,7 +1075,7 @@ class TypeChecker::ConstraintTypeBuilder {
                         Nonnull<GenericBinding*> self_binding)
       : self_binding_(PrepareSelfBinding(arena, self_binding)),
         impl_binding_(AddImplBinding(arena, self_binding_)) {}
-  ConstraintTypeBuilder(Nonnull<Arena*> arena,
+  ConstraintTypeBuilder(Nonnull<Arena*> /*arena*/,
                         Nonnull<GenericBinding*> self_binding,
                         Nonnull<ImplBinding*> impl_binding)
       : self_binding_(self_binding), impl_binding_(impl_binding) {}
@@ -1329,7 +1328,6 @@ class TypeChecker::ConstraintTypeBuilder {
     return impl_binding;
   }
 
- private:
   Nonnull<GenericBinding*> self_binding_;
   Nonnull<ImplBinding*> impl_binding_;
   std::vector<ConstraintType::ImplConstraint> impl_constraints_;
@@ -1406,7 +1404,7 @@ auto TypeChecker::Substitute(const Bindings& bindings,
     return type;
   }
 
-  auto SubstituteIntoBindings =
+  auto substitute_into_bindings =
       [&](Nonnull<const Bindings*> inner_bindings) -> Nonnull<const Bindings*> {
     BindingMap values;
     for (const auto& [name, value] : inner_bindings->args()) {
@@ -1508,14 +1506,14 @@ auto TypeChecker::Substitute(const Bindings& bindings,
       Nonnull<const NominalClassType*> new_class_type =
           arena_->New<NominalClassType>(
               &class_type.declaration(),
-              SubstituteIntoBindings(&class_type.bindings()));
+              substitute_into_bindings(&class_type.bindings()));
       return new_class_type;
     }
     case Value::Kind::InterfaceType: {
       const auto& iface_type = cast<InterfaceType>(*type);
       Nonnull<const InterfaceType*> new_iface_type = arena_->New<InterfaceType>(
           &iface_type.declaration(),
-          SubstituteIntoBindings(&iface_type.bindings()));
+          substitute_into_bindings(&iface_type.bindings()));
       return new_iface_type;
     }
     case Value::Kind::ConstraintType: {
@@ -1564,7 +1562,8 @@ auto TypeChecker::Substitute(const Bindings& bindings,
     case Value::Kind::ImplWitness: {
       const auto& witness = cast<ImplWitness>(*type);
       return arena_->New<ImplWitness>(
-          &witness.declaration(), SubstituteIntoBindings(&witness.bindings()));
+          &witness.declaration(),
+          substitute_into_bindings(&witness.bindings()));
     }
     case Value::Kind::BindingWitness: {
       auto it =
@@ -1695,9 +1694,9 @@ auto TypeChecker::MatchImpl(const InterfaceType& iface,
 }
 
 auto TypeChecker::MakeConstraintWitness(
-    const ConstraintType& constraint,
+    const ConstraintType& /*constraint*/,
     std::vector<Nonnull<const Witness*>> impl_constraint_witnesses,
-    SourceLocation source_loc) const -> Nonnull<const Witness*> {
+    SourceLocation /*source_loc*/) const -> Nonnull<const Witness*> {
   return arena_->New<ConstraintWitness>(std::move(impl_constraint_witnesses));
 }
 
@@ -1769,7 +1768,7 @@ auto TypeChecker::DeduceCallBindings(
     CallExpression& call, Nonnull<const Value*> params_type,
     llvm::ArrayRef<FunctionType::GenericParameter> generic_params,
     llvm::ArrayRef<Nonnull<const GenericBinding*>> deduced_bindings,
-    llvm::ArrayRef<Nonnull<const ImplBinding*>> impl_bindings,
+    llvm::ArrayRef<Nonnull<const ImplBinding*>> /*impl_bindings*/,
     const ImplScope& impl_scope) -> ErrorOr<Success> {
   llvm::ArrayRef<Nonnull<const Value*>> params =
       cast<TupleValue>(*params_type).elements();
@@ -1838,7 +1837,7 @@ auto TypeChecker::LookupInConstraint(SourceLocation source_loc,
       // constraints.
       continue;
     }
-    const InterfaceType& iface_type = cast<InterfaceType>(*lookup.context);
+    const auto& iface_type = cast<InterfaceType>(*lookup.context);
     if (std::optional<Nonnull<const Declaration*>> member =
             FindMember(member_name, iface_type.declaration().members());
         member.has_value()) {
@@ -2284,7 +2283,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
                      << " does not have a field named " << access.member_name();
             }
             case Value::Kind::ChoiceType: {
-              const ChoiceType& choice = cast<ChoiceType>(*type);
+              const auto& choice = cast<ChoiceType>(*type);
               std::optional<Nonnull<const Value*>> parameter_types =
                   choice.FindAlternative(access.member_name());
               if (!parameter_types.has_value()) {
@@ -2310,8 +2309,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
               return Success();
             }
             case Value::Kind::NominalClassType: {
-              const NominalClassType& class_type =
-                  cast<NominalClassType>(*type);
+              const auto& class_type = cast<NominalClassType>(*type);
               CARBON_ASSIGN_OR_RETURN(
                   auto type_member,
                   FindMixedMemberAndType(
@@ -2445,7 +2443,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
         access.set_impl(impl);
       }
 
-      auto SubstituteIntoMemberType = [&]() {
+      auto substitute_into_member_type = [&]() {
         Nonnull<const Value*> member_type = &member_name.member().type();
         if (member_name.interface()) {
           Nonnull<const InterfaceType*> iface_type = *member_name.interface();
@@ -2465,7 +2463,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
                    : DeclarationKind::VariableDeclaration) {
         case DeclarationKind::VariableDeclaration:
           if (has_instance) {
-            access.set_static_type(SubstituteIntoMemberType());
+            access.set_static_type(substitute_into_member_type());
             access.set_value_category(access.object().value_category());
             return Success();
           }
@@ -2477,14 +2475,14 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
             CARBON_CHECK(!has_instance || is_instance_member ||
                          !member_name.base_type().has_value())
                 << "vacuous compound member access";
-            access.set_static_type(SubstituteIntoMemberType());
+            access.set_static_type(substitute_into_member_type());
             access.set_value_category(ValueCategory::Let);
             return Success();
           }
           break;
         }
         case DeclarationKind::AssociatedConstantDeclaration:
-          access.set_static_type(SubstituteIntoMemberType());
+          access.set_static_type(substitute_into_member_type());
           access.set_value_category(access.object().value_category());
           return Success();
         default:
@@ -2839,7 +2837,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
           // TODO: Remove Print special casing once we have variadics or
           // overloads. Here, that's the name Print instead of __intrinsic_print
           // in errors.
-          if (args.size() < 1 || args.size() > 2) {
+          if (args.empty() || args.size() > 2) {
             return ProgramError(e->source_loc())
                    << "Print takes 1 or 2 arguments, received " << args.size();
           }
@@ -3411,9 +3409,10 @@ auto TypeChecker::TypeCheckPattern(
         }
         CARBON_RETURN_IF_ERROR(TypeCheckPattern(
             field, expected_field_type, impl_scope, enclosing_value_category));
-        if (trace_stream_)
+        if (trace_stream_) {
           **trace_stream_ << "finished checking tuple pattern field " << *field
                           << "\n";
+        }
         field_types.push_back(&field->static_type());
       }
       tuple.set_static_type(arena_->New<TupleValue>(std::move(field_types)));
@@ -3433,7 +3432,7 @@ auto TypeChecker::TypeCheckPattern(
         return ProgramError(alternative.source_loc())
                << "alternative pattern does not name a choice type.";
       }
-      const ChoiceType& choice_type = cast<ChoiceType>(*type);
+      const auto& choice_type = cast<ChoiceType>(*type);
       if (expected) {
         CARBON_RETURN_IF_ERROR(ExpectType(alternative.source_loc(),
                                           "alternative pattern", &choice_type,
@@ -3926,8 +3925,9 @@ auto TypeChecker::TypeCheckCallableDeclaration(Nonnull<CallableDeclaration*> f,
     function_scope.AddParent(&impl_scope);
     BringImplsIntoScope(cast<FunctionType>(f->static_type()).impl_bindings(),
                         function_scope);
-    if (trace_stream_)
+    if (trace_stream_) {
       **trace_stream_ << function_scope;
+    }
     CARBON_RETURN_IF_ERROR(TypeCheckStmt(*f->body(), function_scope));
     if (!f->return_term().is_omitted()) {
       CARBON_RETURN_IF_ERROR(
@@ -4330,7 +4330,7 @@ auto TypeChecker::CheckImplIsDeducible(
     SourceLocation source_loc, Nonnull<const Value*> impl_type,
     Nonnull<const InterfaceType*> impl_iface,
     llvm::ArrayRef<Nonnull<const GenericBinding*>> deduced_bindings,
-    const ImplScope& impl_scope) -> ErrorOr<Success> {
+    const ImplScope& /*impl_scope*/) -> ErrorOr<Success> {
   ArgumentDeduction deduction(source_loc, "impl", deduced_bindings,
                               trace_stream_);
   CARBON_RETURN_IF_ERROR(deduction.Deduce(impl_type, impl_type,
@@ -4348,7 +4348,7 @@ auto TypeChecker::CheckImplIsDeducible(
 auto TypeChecker::CheckImplIsComplete(Nonnull<const InterfaceType*> iface_type,
                                       Nonnull<const ImplDeclaration*> impl_decl,
                                       Nonnull<const Value*> self_type,
-                                      Nonnull<const Witness*> self_witness,
+                                      Nonnull<const Witness*> /*self_witness*/,
                                       Nonnull<const Witness*> iface_witness,
                                       const ImplScope& impl_scope)
     -> ErrorOr<Success> {
@@ -4663,7 +4663,7 @@ auto TypeChecker::TypeCheckChoiceDeclaration(
   return Success();
 }
 
-static bool IsValidTypeForAliasTarget(Nonnull<const Value*> type) {
+static auto IsValidTypeForAliasTarget(Nonnull<const Value*> type) -> bool {
   switch (type->kind()) {
     case Value::Kind::IntValue:
     case Value::Kind::FunctionValue:

+ 3 - 3
explorer/interpreter/type_checker.h

@@ -40,7 +40,7 @@ class TypeChecker {
   // Construct a type that is the same as `type` except that occurrences
   // of type variables (aka. `GenericBinding` and references to `ImplBinding`)
   // are replaced by their corresponding type or witness in `dict`.
-  auto Substitute(const Bindings& dict, Nonnull<const Value*> type) const
+  auto Substitute(const Bindings& bindings, Nonnull<const Value*> type) const
       -> Nonnull<const Value*>;
 
   // If `impl` can be an implementation of interface `iface` for the given
@@ -60,7 +60,7 @@ class TypeChecker {
   auto FindMixedMemberAndType(SourceLocation source_loc,
                               const std::string_view& name,
                               llvm::ArrayRef<Nonnull<Declaration*>> members,
-                              const Nonnull<const Value*> enclosing_type)
+                              Nonnull<const Value*> enclosing_type)
       -> ErrorOr<std::optional<
           std::pair<Nonnull<const Value*>, Nonnull<const Declaration*>>>>;
 
@@ -300,7 +300,7 @@ class TypeChecker {
 
   // Type check all the members of the implementation.
   auto TypeCheckImplDeclaration(Nonnull<ImplDeclaration*> impl_decl,
-                                const ImplScope& impl_scope)
+                                const ImplScope& enclosing_scope)
       -> ErrorOr<Success>;
 
   // This currently does nothing, but perhaps that will change in the future.

+ 8 - 9
explorer/interpreter/value.cpp

@@ -20,7 +20,6 @@ namespace Carbon {
 using llvm::cast;
 using llvm::dyn_cast;
 using llvm::dyn_cast_or_null;
-using llvm::isa;
 
 auto StructValue::FindField(std::string_view name) const
     -> std::optional<Nonnull<const Value*>> {
@@ -39,7 +38,7 @@ static auto GetMember(Nonnull<Arena*> arena, Nonnull<const Value*> v,
   std::string_view f = field.name();
 
   if (field.witness().has_value()) {
-    Nonnull<const Witness*> witness = cast<Witness>(*field.witness());
+    auto witness = cast<Witness>(*field.witness());
 
     // Associated constants.
     if (auto* assoc_const = dyn_cast_or_null<AssociatedConstantDeclaration>(
@@ -104,7 +103,7 @@ static auto GetMember(Nonnull<Arena*> arena, Nonnull<const Value*> v,
                                           << " or its " << class_type;
         } else if ((*func)->declaration().is_method()) {
           // Found a method. Turn it into a bound method.
-          const FunctionValue& m = cast<FunctionValue>(**func);
+          const auto& m = cast<FunctionValue>(**func);
           return arena->New<BoundMethodValue>(&m.declaration(), me_value,
                                               &class_type.bindings());
         } else {
@@ -125,7 +124,7 @@ static auto GetMember(Nonnull<Arena*> arena, Nonnull<const Value*> v,
     }
     case Value::Kind::NominalClassType: {
       // Access a class function.
-      const NominalClassType& class_type = cast<NominalClassType>(*v);
+      const auto& class_type = cast<NominalClassType>(*v);
       std::optional<Nonnull<const FunctionValue*>> fun =
           class_type.FindFunction(f);
       if (fun == std::nullopt) {
@@ -178,7 +177,7 @@ static auto SetFieldImpl(
       return arena->New<StructValue>(elements);
     }
     case Value::Kind::NominalClassValue: {
-      const NominalClassValue& object = cast<NominalClassValue>(*value);
+      const auto& object = cast<NominalClassValue>(*value);
       CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> inits,
                               SetFieldImpl(arena, &object.inits(), path_begin,
                                            path_end, field_value, source_loc));
@@ -207,7 +206,7 @@ auto Value::SetField(Nonnull<Arena*> arena, const FieldPath& path,
                      Nonnull<const Value*> field_value,
                      SourceLocation source_loc) const
     -> ErrorOr<Nonnull<const Value*>> {
-  return SetFieldImpl(arena, Nonnull<const Value*>(this),
+  return SetFieldImpl(arena, static_cast<Nonnull<const Value*>>(this),
                       path.components_.begin(), path.components_.end(),
                       field_value, source_loc);
 }
@@ -287,14 +286,14 @@ void Value::Print(llvm::raw_ostream& out) const {
       out << (cast<BoolValue>(*this).value() ? "true" : "false");
       break;
     case Value::Kind::DestructorValue: {
-      const DestructorValue& destructor = cast<DestructorValue>(*this);
+      const auto& destructor = cast<DestructorValue>(*this);
       out << "destructor [ ";
       out << destructor.declaration().me_pattern();
       out << " ]";
       break;
     }
     case Value::Kind::FunctionValue: {
-      const FunctionValue& fun = cast<FunctionValue>(*this);
+      const auto& fun = cast<FunctionValue>(*this);
       out << "fun<" << fun.declaration().name() << ">";
       if (!fun.type_args().empty()) {
         out << "[";
@@ -315,7 +314,7 @@ void Value::Print(llvm::raw_ostream& out) const {
       break;
     }
     case Value::Kind::BoundMethodValue: {
-      const BoundMethodValue& method = cast<BoundMethodValue>(*this);
+      const auto& method = cast<BoundMethodValue>(*this);
       out << "bound_method<" << method.declaration().name() << ">";
       if (!method.type_args().empty()) {
         out << "[";

+ 6 - 7
explorer/interpreter/value.h

@@ -119,7 +119,7 @@ class Value {
 
 // Returns whether the fully-resolved kind that this value will eventually have
 // is currently unknown, because it depends on a generic parameter.
-inline bool IsValueKindDependent(Nonnull<const Value*> type) {
+inline auto IsValueKindDependent(Nonnull<const Value*> type) -> bool {
   return type->kind() == Value::Kind::VariableType ||
          type->kind() == Value::Kind::AssociatedConstant;
 }
@@ -352,8 +352,8 @@ class AlternativeConstructorValue : public Value {
   AlternativeConstructorValue(std::string_view alt_name,
                               std::string_view choice_name)
       : Value(Kind::AlternativeConstructorValue),
-        alt_name_(std::move(alt_name)),
-        choice_name_(std::move(choice_name)) {}
+        alt_name_(alt_name),
+        choice_name_(choice_name) {}
 
   static auto classof(const Value* value) -> bool {
     return value->kind() == Kind::AlternativeConstructorValue;
@@ -373,8 +373,8 @@ class AlternativeValue : public Value {
   AlternativeValue(std::string_view alt_name, std::string_view choice_name,
                    Nonnull<const Value*> argument)
       : Value(Kind::AlternativeValue),
-        alt_name_(std::move(alt_name)),
-        choice_name_(std::move(choice_name)),
+        alt_name_(alt_name),
+        choice_name_(choice_name),
         argument_(argument) {}
 
   static auto classof(const Value* value) -> bool {
@@ -398,7 +398,7 @@ class TupleValue : public Value {
   static auto Empty() -> Nonnull<const TupleValue*> {
     static const TupleValue empty =
         TupleValue(std::vector<Nonnull<const Value*>>());
-    return Nonnull<const TupleValue*>(&empty);
+    return static_cast<Nonnull<const TupleValue*>>(&empty);
   }
 
   explicit TupleValue(std::vector<Nonnull<const Value*>> elements)
@@ -788,7 +788,6 @@ class ConstraintType : public Value {
     Nonnull<const Value*> context;
   };
 
- public:
   explicit ConstraintType(Nonnull<const GenericBinding*> self_binding,
                           std::vector<ImplConstraint> impl_constraints,
                           std::vector<EqualityConstraint> equality_constraints,

+ 2 - 2
migrate_cpp/output_segment.h

@@ -37,7 +37,7 @@ class OutputSegment {
   // instead. However, most other types we intend to support as they become
   // necessary.
   template <typename T>
-  static constexpr bool IsSupportedClangASTNodeType() {
+  static constexpr auto IsSupportedClangASTNodeType() -> bool {
     return std::is_convertible_v<T*, clang::Stmt*> ||
            std::is_convertible_v<T*, clang::Decl*>;
   }
@@ -62,7 +62,7 @@ class OutputSegment {
   friend struct OutputWriter;
 
   template <typename T>
-  T& AssertNotNull(T* ptr) {
+  auto AssertNotNull(T* ptr) -> T& {
     CARBON_CHECK(ptr != nullptr);
     return *ptr;
   }

+ 5 - 5
migrate_cpp/rewriter.cpp

@@ -16,18 +16,18 @@ auto OutputWriter::Write(clang::SourceLocation loc,
                          const OutputSegment& segment) const -> bool {
   return std::visit(
       [&](auto& content) {
-        using type = std::decay_t<decltype(content)>;
+        using Type = std::decay_t<decltype(content)>;
         auto [begin, end] = bounds;
 
-        if constexpr (std::is_same_v<type, std::string>) {
+        if constexpr (std::is_same_v<Type, std::string>) {
           auto begin_offset = source_manager.getDecomposedLoc(loc).second;
           // Append the string replacement if the node being replaced falls
           // within `bounds`.
           if (begin <= begin_offset && begin_offset < end) {
             output.append(content);
           }
-        } else if constexpr (std::is_same_v<type, clang::DynTypedNode> ||
-                             std::is_same_v<type, clang::TypeLoc>) {
+        } else if constexpr (std::is_same_v<Type, clang::DynTypedNode> ||
+                             std::is_same_v<Type, clang::TypeLoc>) {
           auto content_loc = content.getSourceRange().getBegin();
           auto begin_offset =
               source_manager.getDecomposedLoc(content_loc).second;
@@ -54,7 +54,7 @@ auto OutputWriter::Write(clang::SourceLocation loc,
             }
           }
         } else {
-          static_assert(std::is_void_v<type>,
+          static_assert(std::is_void_v<Type>,
                         "Failed to handle a case in the `std::variant`.");
         }
         return true;

+ 17 - 12
migrate_cpp/rewriter.h

@@ -22,10 +22,14 @@ namespace Carbon {
 namespace Internal {
 
 struct Empty {
-  friend bool operator==(Empty, Empty) { return true; }
+  friend auto operator==(Empty /*unused*/, Empty /*unused*/) -> bool {
+    return true;
+  }
 };
 struct Tombstone {
-  friend bool operator==(Tombstone, Tombstone) { return true; }
+  friend auto operator==(Tombstone /*unused*/, Tombstone /*unused*/) -> bool {
+    return true;
+  }
 };
 
 // Type alias for the variant representing any of the values that can be
@@ -36,16 +40,16 @@ using KeyType =
 // `KeyInfo` is used as a template argument to `llvm::DenseMap` to specify how
 // to equality-compare and hash `KeyType`.
 struct KeyInfo {
-  static bool isEqual(const KeyType& lhs, const KeyType& rhs) {
+  static auto isEqual(const KeyType& lhs, const KeyType& rhs) -> bool {
     return lhs == rhs;
   }
-  static unsigned getHashValue(const KeyType& x) {
+  static auto getHashValue(const KeyType& x) -> unsigned {
     return std::visit(
         [](auto x) -> unsigned {
-          using type = std::decay_t<decltype(x)>;
-          if constexpr (std::is_same_v<type, clang::DynTypedNode>) {
+          using Type = std::decay_t<decltype(x)>;
+          if constexpr (std::is_same_v<Type, clang::DynTypedNode>) {
             return clang::DynTypedNode::DenseMapInfo::getHashValue(x);
-          } else if constexpr (std::is_same_v<type, clang::TypeLoc>) {
+          } else if constexpr (std::is_same_v<Type, clang::TypeLoc>) {
             // TODO: Improve this.
             return reinterpret_cast<uintptr_t>(x.getTypePtr());
           } else {
@@ -55,8 +59,8 @@ struct KeyInfo {
         x);
   }
 
-  static KeyType getEmptyKey() { return Empty{}; }
-  static KeyType getTombstoneKey() { return Tombstone{}; }
+  static auto getEmptyKey() -> KeyType { return Empty{}; }
+  static auto getTombstoneKey() -> KeyType { return Tombstone{}; }
 };
 
 }  // namespace Internal
@@ -177,7 +181,7 @@ class MigrationConsumer : public clang::ASTConsumer {
  public:
   explicit MigrationConsumer(std::string& result,
                              std::pair<size_t, size_t> output_range)
-      : result_(result), output_range_(output_range) {}
+      : result_(result), output_range_(std::move(output_range)) {}
 
   auto HandleTranslationUnit(clang::ASTContext& context) -> void override;
 
@@ -199,11 +203,12 @@ class MigrationAction : public clang::ASTFrontendAction {
   // `output_range.second` will be written.
   explicit MigrationAction(std::string& result,
                            std::pair<size_t, size_t> output_range)
-      : result_(result), output_range_(output_range) {}
+      : result_(result), output_range_(std::move(output_range)) {}
 
   // Returns a `std::unique_ptr` to a `clang::MigrationConsumer` which populates
   // the output `result`.
-  auto CreateASTConsumer(clang::CompilerInstance&, llvm::StringRef)
+  auto CreateASTConsumer(clang::CompilerInstance& /*CI*/,
+                         llvm::StringRef /*InFile*/)
       -> std::unique_ptr<clang::ASTConsumer> override {
     return std::make_unique<MigrationConsumer>(result_, output_range_);
   }

+ 5 - 3
migrate_cpp/rewriter_test.cpp

@@ -19,7 +19,7 @@ namespace {
 // an annotated range.
 class Annotations {
  public:
-  Annotations(llvm::StringRef annotated_source) {
+  explicit Annotations(llvm::StringRef annotated_source) {
     size_t index = annotated_source.find("$[[");
     if (index == llvm::StringRef::npos) {
       source_code_ = std::string(annotated_source);
@@ -39,11 +39,13 @@ class Annotations {
   }
 
   // Returns a view into the unannotated source.
-  llvm::StringRef source() const { return source_code_; }
+  auto source() const -> llvm::StringRef { return source_code_; }
 
   // Returns the offsets in the file representing the annotated range if they
   // exist and `{0, std::numeric_limits<size_t>::max()}` otherwise.
-  std::pair<size_t, size_t> range() const { return std::pair(start_, end_); }
+  auto range() const -> std::pair<size_t, size_t> {
+    return std::pair(start_, end_);
+  }
 
  private:
   std::string source_code_;

+ 8 - 10
scripts/create_compdb.py

@@ -57,7 +57,7 @@ print("Building compilation database...")
 # stand-alone files. This is a bit simpler than scraping the actual compile
 # actions and allows us to directly index header-only libraries easily and
 # pro-actively index the specific headers in the project.
-source_files_query = subprocess.run(
+source_files_query = subprocess.check_output(
     [
         bazel,
         "query",
@@ -67,11 +67,9 @@ source_files_query = subprocess.run(
         "--incompatible_display_source_file_location",
         'filter(".*\\.(h|cpp|cc|c|cxx)$", kind("source file", deps(//...)))',
     ],
-    check=True,
-    stdout=subprocess.PIPE,
     stderr=subprocess.DEVNULL,
     universal_newlines=True,
-).stdout
+)
 source_files = [
     Path(line.split(":")[0]) for line in source_files_query.splitlines()
 ]
@@ -98,7 +96,7 @@ print(
 
 # Now collect the generated file labels.
 # cc_proto_library generates files, but they aren't seen with "generated file".
-generated_file_labels = subprocess.run(
+generated_file_labels = subprocess.check_output(
     [
         bazel,
         "query",
@@ -111,23 +109,21 @@ generated_file_labels = subprocess.run(
             'kind("cc_proto_library", deps(//...))'
         ),
     ],
-    check=True,
-    stdout=subprocess.PIPE,
     stderr=subprocess.DEVNULL,
     universal_newlines=True,
-).stdout.splitlines()
+).splitlines()
 print("Found %d generated files..." % (len(generated_file_labels),))
 
 # Directly build these labels so that indexing can find them. Allow this to
 # fail in case there are build errors in the client, and just warn the user
 # that they may be missing generated files.
 print("Building the generated files so that tools can find them...")
-subprocess.run([bazel, "build", "--keep_going"] + generated_file_labels)
+subprocess.check_call([bazel, "build", "--keep_going"] + generated_file_labels)
 
 # Also build some specific targets that depend on external packages so those are
 # fetched and linked into the Bazel execution root. We try to use cheap files
 # where possible, but in some cases need to create a virtual include directory.
-subprocess.run(
+subprocess.check_call(
     [
         bazel,
         "build",
@@ -137,6 +133,8 @@ subprocess.run(
         "@com_google_googletest//:LICENSE",
         "@com_googlesource_code_re2//:LICENSE",
         "@com_github_google_benchmark//:benchmark",
+        "@com_google_libprotobuf_mutator//:LICENSE",
+        "@com_google_protobuf//:any_proto",
     ]
 )
 

+ 35 - 16
scripts/run_clang_tidy.py

@@ -1,7 +1,6 @@
 #!/usr/bin/env python3
 
-"""Runs clang-tidy over all Carbon files.
-"""
+"""Runs clang-tidy over all Carbon files."""
 
 __copyright__ = """
 Part of the Carbon Language project, under the Apache License v2.0 with LLVM
@@ -9,33 +8,53 @@ Exceptions. See /LICENSE for license information.
 SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 """
 
+import argparse
 import os
+import re
 import subprocess
-import sys
 
 from pathlib import Path
 
 
 def main() -> None:
+    parser = argparse.ArgumentParser(__doc__)
+    # Copied from run-clang-tidy.py for forwarding.
+    parser.add_argument("-fix", action="store_true", help="Apply fix-its")
+    # Local flags.
+    parser.add_argument("files", nargs="*", help="Files to fix")
+    parsed_args = parser.parse_args()
+
+    # If files are passed in, resolve them; otherwise, add a path filter.
+    if parsed_args.files:
+        files = [str(Path(f).resolve()) for f in parsed_args.files]
+    else:
+        files = ["^(?!.*/(bazel-|third_party)).*$"]
+
     # Set the repo root as the working directory.
-    os.chdir(Path(__file__).parent.parent)
+    os.chdir(Path(__file__).resolve().parent.parent)
     # Ensure create_compdb has been run.
     subprocess.check_call(["./scripts/create_compdb.py"])
 
-    args = sys.argv[1:]
-    if not args or args[0] == "--fix":
-        args.append("^(?!.*/(bazel-|third_party)).*$")
+    # Use the run-clang-tidy version that should be with the rest of the clang
+    # toolchain. This exposes us to version skew with user-installed clang
+    # versions, but avoids version skew between the script and clang-tidy
+    # itself.
+    with Path(
+        "./bazel-execroot/external/bazel_cc_toolchain/"
+        "clang_detected_variables.bzl"
+    ).open() as f:
+        clang_vars = f.read()
+    clang_bindir_match = re.search(r"clang_bindir = \"(.*)\"", clang_vars)
+    assert clang_bindir_match is not None, clang_vars
+
+    args = [str(Path(clang_bindir_match[1]).joinpath("run-clang-tidy"))]
+
+    # Forward flags.
+    if parsed_args.fix:
+        args.append("-fix")
 
     # Run clang-tidy from clang-tools-extra.
-    exit(
-        subprocess.call(
-            [
-                "./bazel-execroot/external/llvm-project/clang-tools-extra/"
-                "clang-tidy/tool/run-clang-tidy.py",
-            ]
-            + args
-        )
-    )
+    exit(subprocess.call(args + files))
 
 
 if __name__ == "__main__":

+ 3 - 1
third_party/libprotobuf_mutator/BUILD.txt

@@ -5,6 +5,8 @@
 # libprotobuf_mutator uses cmake and doesn't provide a bazel BUILD file.
 # See https://github.com/google/libprotobuf-mutator/issues/91.
 
+exports_files(["LICENSE"])
+
 cc_library(
     name = "libprotobuf_mutator",
     srcs = glob(
@@ -16,7 +18,7 @@ cc_library(
         exclude = ["**/*_test.cc"],
     ),
     hdrs = ["src/libfuzzer/libfuzzer_macro.h"],
-    include_prefix = "libprotobuf_mutator",
+    strip_include_prefix = "src",
     visibility = ["//visibility:public"],
     deps = ["@com_google_protobuf//:protobuf"],
 )

+ 1 - 1
toolchain/lexer/token_kind_test.cpp

@@ -19,7 +19,7 @@ using ::testing::MatchesRegex;
 // We restrict symbols to punctuation characters that are expected to be widely
 // available on modern keyboards used for programming.
 constexpr llvm::StringLiteral SymbolRegex =
-    "[\\[\\]{}!@#%^&*()/?\\\\|;:.,<>=+~-]+";
+    R"([\[\]{}!@#%^&*()/?\\|;:.,<>=+~-]+)";
 
 // We restrict keywords to be lowercase ASCII letters and underscores.
 constexpr llvm::StringLiteral KeywordRegex = "[a-z_]+";

+ 1 - 1
toolchain/semantics/node_ref.h

@@ -16,7 +16,7 @@ namespace Carbon::Semantics {
 struct NodeStoreIndex {
   explicit NodeStoreIndex(int32_t index) : index(index) {}
 
-  operator int32_t() const { return index; }
+  explicit operator int32_t() const { return index; }
 
   int32_t index;
 };