Skip to content

Enforce protected beyond top-level namespace#17115

Open
jgaskins wants to merge 1 commit into
crystal-lang:masterfrom
jgaskins:enforce-protected-beyond-top-level-namespace
Open

Enforce protected beyond top-level namespace#17115
jgaskins wants to merge 1 commit into
crystal-lang:masterfrom
jgaskins:enforce-protected-beyond-top-level-namespace

Conversation

@jgaskins

@jgaskins jgaskins commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Fixes #16827

Notably, there were a couple places in the spec suite that called protected methods on Spec::ExampleGroup, which worked because the top level includes Spec::Methods. That effectively makes every protected method in every type nested under Spec public, which is a symptom of the problem we're fixing here.

My workaround for that here was to wrap those calls in a Spec type specifically for this spec suite (not intended to be used by regular Crystal apps/shards), which highlights that being able to call protected methods from within the namespace is preserved. I'm not a huge fan of the monkeypatch, but the alternative was to make Spec::ExampleGroup#report public. Notably, Spec::RootContext#report is already public but Spec::ExampleGroup#report is protected, so it seems feasible to make it public at least to bring that method into parity between the two Spec::Context concrete types, but my initial implementation preserves the existing visibility in the stdlib until we discuss whether it should change.

Consider this code:

    module A
      module Validations
      end

      struct Query
        protected def this_method_is_protected
          "this_method_is_protected!!!"
        end
      end
    end

    struct B
      include A::Validations

      def call
        puts A::Query.new.this_method_is_protected
      end
    end

    B.new.call

`B#call` calls a protected method on `A::Query`, but it has no
relationship with `A::Query`. It does include `A::Validations`, but
that should not give B the same access to `A::Query`'s protected methods
that `A::Validations` has.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Including a namespaced mixin gives access to all protected methods for a different nested type in the same top-level namespace

1 participant