Skip to content

Add type restrictions to Log directory #15777

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

Vici37
Copy link
Contributor

@Vici37 Vici37 commented May 15, 2025

This is the output of compiling cr-source-typer and running it with the below incantation:

CRYSTAL_PATH="./src:lib" ./typify spec/all_spec.cr 
--error-trace 
--exclude src/crystal/ 
--stats --progress 
--ignore-private-defs 
--ignore-protected-defs 
--union-size-threshold 2 
--include-splats 
src/log

This is related to #15682 .

@Vici37 Vici37 changed the title Add type restrictions to log directory Add type restrictions to log directory May 15, 2025
@Vici37 Vici37 changed the title Add type restrictions to log directory Add type restrictions to Log directory May 15, 2025
@@ -14,7 +14,7 @@ class Log

# Creates an instance of a `Log::Formatter` that calls
# the specified `Proc` for every entry
def self.new(&proc : (Log::Entry, IO) ->)
def self.new(&proc : (Log::Entry, IO) ->) : self
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.new methods are always returning self, making return type annotation IMO pretty redundant.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For documentation purpose, yes, but there are cases where the compiler doesn't always infer that a specific .new returns a self.

@@ -118,7 +118,7 @@ class Log
# It doesn't write any output if the context is empty.
# Parameters `before` and `after` can be provided to be written around
# the value.
def context(*, before = nil, after = nil)
def context(*, before : _ = nil, after : _ = nil) : Nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we're on the side of preferring no type restriction instead of _ or forall if the type can't be restricted. See #15334

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the type is really unrestricted - like in this case - I think it makes a lot of sense to explicate that in the type restriction _.
Otherwise, it would be indiscernible from an unknown type restriction.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is also my preference, especially from a documentation perspective, but I know others on the team disagreed.

Another alternative proposed in that issue:

def context(*, before : B = nil, after : A = nil) : Nil forall A, B
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_ is more concise than forall, so I'd use that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants