Skip to content

Several false positives for whitespace/indent_namespace #401

Open

Description

@gmackey

Attached is a file that has some simple examples that cause false positives for indenting inside a namespace. These all worked with 1.6.1. They appeared when upgrading to 2.0.2.

example.cpp

The content of the file is pasted here, too:

// Copyright 2025 NoSuchCompany

#include <cstdint>
#include <memory>
#include <vector>

namespace test {

// After assignment operator.
constexpr int64_t kTestConstant =
    123;

using NewInt =
    int64_t;


// Inside braces.
enum class TestEnumType : uint8_t { kOne,
                                    kTwo,
                                    kThree };


// Inside template.
template <typename T>
class TestVector : std::vector<
    T> { };

template <typename Type1,
          typename Type2>
void TestFunc(const Type1 &var1, Type2 &var2);

using TestVector = std::vector<
                       int64_t>;

template <typename T>
using TestVectorPointer = std::shared_ptr<
        std::vector<
            T>>;

}  // namespace test

Activity

  1. aaronliu0130 commented on Oct 27, 2025

    @aaronliu0130
    Member

    Can you confirm if #376 would fix the issues? It's sat there for half a year because the other maintainers—whose approval is needed to merge the PR—are not active.

  2. gmackey commented on Dec 8, 2025

    @gmackey
    Author

    I tested against #376 and it didn't fix any of the issues.

  3. janmarsino98 commented on Jul 14, 2026

    @janmarsino98
    Contributor

    I reproduced all eight whitespace/indent_namespace false positives from the report on current develop. The regression is in the namespace-candidate predicate: the old logic only ran the rule after adding a namespace child with check_namespace_indentation, while the current CheckForNamespaceIndentation treats every line whose stack top or previous top is a namespace as a candidate. That makes continuations of assignments, using aliases, enum bodies, and template arguments look like namespace-level declarations. I am preparing a focused regression test for the reported forms and a narrow restoration of the child-block predicate, retaining the newer wrapped-block handling rather than adding per-example exemptions. Is this issue available for me to take?

  4. janmarsino98 commented on Jul 14, 2026

    @janmarsino98
    Contributor

    Follow-up from a local prototype: a continuation-aware suppression resolves all reported forms and preserves the focused positive tests, but the full CLI suite then changes many existing namespace-indentation expectations in Chromium, Boost, and Protobuf fixtures. The current rule intentionally reports multiline namespace-level initializers in those samples, so this is a policy change rather than a narrow parser correction. I will not open a broad PR without guidance. Could a maintainer clarify the intended boundary: should expression continuations at namespace scope be exempt generally, and should the sample-output baseline be updated accordingly?

  5. aaronliu0130 commented on Jul 15, 2026

    @aaronliu0130
    Member

    @janmarsino98 I'm not sure what you're saying. If you're using AI to write your comments, could you use your own words instead?

  6. aaronliu0130 commented on Jul 15, 2026

    @aaronliu0130
    Member

    Annotated:

    // Copyright 2025 NoSuchCompany
    
    #include <cstdint>
    #include <memory>
    #include <vector>
    
    namespace test {
    
    // After assignment operator.
    /* Not sure if we should fix these, as it means we need to add NestingState parsing for all assignments. That's a lot of processing to address a rare issue that typically means you're doing something horrid to merit having to split the assignment into multiple lines.
    I can change my mind upon seeing examples of good code that would trip the false positive. */
    constexpr int64_t kTestConstant =
        123;
    
    using NewInt =
        int64_t;
    
    
    // Inside braces.
    /* This one should be fixed by #376. */
    enum class TestEnumType : uint8_t { kOne,
                                        kTwo,
                                        kThree };
    
    
    // Inside template.
    template <typename T>
    class TestVector : std::vector< /* Same as vector<int64_t> example below. */
        T> { };
    
    /* This one probably merits a fix. */
    template <typename Type1,
              typename Type2>
    void TestFunc(const Type1 &var1, Type2 &var2);
    
    /* This one I don't think so. Could change mind upon example. */
    using TestVector = std::vector<
                           int64_t>;
    
    /* Ditto. */
    template <typename T>
    using TestVectorPointer = std::shared_ptr<
            std::vector<
                T>>;
    
    }  // namespace test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions