Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 0 additions & 21 deletions spec/std/set_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,6 @@ describe "Set" do
set3.should eq(Set{1, 3, 5})
end

it "does -" do
set1 = Set{1, 2, 3, 4, 5}
set2 = [2, 4, 'a']
set3 = set1 - set2
set3.should eq(Set{1, 3, 5})
end

it "does -" do
set1 = Set{1, 2, 3, 4, 'b'}
set2 = [2, 4, 5]
Expand Down Expand Up @@ -241,13 +234,6 @@ describe "Set" do
set1.should eq(Set{1, 3, 5})
end

it "does subtract" do
set1 = Set{1, 2, 3, 4, 5}
set2 = Set{2, 4, 'a'}
set1.subtract set2
set1.should eq(Set{1, 3, 5})
end

it "does subtract" do
set1 = Set{1, 2, 3, 4, 'b'}
set2 = Set{2, 4, 5}
Expand All @@ -262,13 +248,6 @@ describe "Set" do
set1.should eq(Set{1, 3, 5})
end

it "does subtract" do
set1 = Set{1, 2, 3, 4, 5}
set2 = [2, 4, 'a']
set1.subtract set2
set1.should eq(Set{1, 3, 5})
end

it "does subtract" do
set1 = Set{1, 2, 3, 4, 'b'}
set2 = [2, 4, 5]
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/crystal/program.cr
Original file line number Diff line number Diff line change
Expand Up @@ -576,11 +576,11 @@ module Crystal
file_module?(filename).try &.lookup_matches(signature)
end

def file_module?(filename)
def file_module?(filename : String)
file_modules[filename]?
end

def file_module(filename)
def file_module(filename : String)
file_modules[filename] ||= FileModule.new(self, self, filename)
end

Expand Down
8 changes: 4 additions & 4 deletions src/compiler/crystal/semantic/type_declaration_processor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ struct Crystal::TypeDeclarationProcessor
ancestor = owner.ancestors.first?
ancestor = uninstantiate(ancestor)
if ancestor
ancestor_non_nilable = @non_nilable_instance_vars[ancestor]?
ancestor_non_nilable = @non_nilable_instance_vars[ancestor]? if ancestor.is_a?(Type)
Comment thread
jgaskins marked this conversation as resolved.
Outdated
end

# If the ancestor has non-nilable instance vars, check that all initialize either call
Expand Down Expand Up @@ -538,7 +538,7 @@ struct Crystal::TypeDeclarationProcessor

owner.ancestors.any? do |ancestor|
ancestor = uninstantiate(ancestor)
@instance_vars_outside[ancestor]?.try &.includes?(name)
@instance_vars_outside[ancestor]?.try &.includes?(name) if ancestor.is_a? Type
end
end

Expand All @@ -553,7 +553,7 @@ struct Crystal::TypeDeclarationProcessor
end

private def compute_non_nilable_outside_single(owner, non_nilable_outisde)
if vars = @instance_vars_outside[owner]?
if owner.is_a?(Type) && (vars = @instance_vars_outside[owner]?)
non_nilable_outisde ||= [] of String
vars.each do |name|
non_nilable_outisde << name unless non_nilable_outisde.includes?(name)
Expand All @@ -570,7 +570,7 @@ struct Crystal::TypeDeclarationProcessor

owner.ancestors.each do |ancestor|
ancestor = uninstantiate(ancestor)
infos = @initialize_infos[ancestor]?
infos = @initialize_infos[ancestor]? if ancestor.is_a?(Type)
return infos if infos && !infos.empty?
end

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/crystal/tools/playground/server.cr
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ module Crystal::Playground

agent_ws = PathWebSocketHandler.new "/agent" do |ws, context|
match_data = context.request.path.not_nil!.match(/\/(\d+)\/(\d+)$/).not_nil!
session_key = match_data[1]?.try(&.to_i)
session_key = match_data[1]?.try(&.to_i) || 0

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why is this needed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

session_key can't be nil because of this line. Because it can't store nil and it's using [] instead of []? below, this line seems like it can't return nil even without this PR or it would raise a KeyError below.

tag = match_data[2]?.try(&.to_i)
@logger.info "#{context.request.path} WebSocket connected (session=#{session_key}, tag=#{tag})"

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/crystal/tools/typed_def_processor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module Crystal::TypedDefProcessor

private def process_result(result : Compiler::Result)
process_type result.program
if file_module = result.program.file_module? target_location.original_filename
if (filename = target_location.original_filename) && (file_module = result.program.file_module?(filename))
process_type file_module
end
end
Expand Down
32 changes: 18 additions & 14 deletions src/hash.cr
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ class Hash(K, V)

# Inserts or updates a key-value pair.
# Returns an `Entry` if it was updated, otherwise `nil`.
private def upsert(key, value) : Entry(K, V)?
private def upsert(key : K, value : V) : Entry(K, V)?
# Empty hash table so only initialize entries for now
if @entries.null?
@indices_size_pow2 = 3
Expand Down Expand Up @@ -416,7 +416,7 @@ class Hash(K, V)

# Implementation of deleting a key.
# Returns the deleted Entry, if it existed, `nil` otherwise.
private def delete_impl(key) : Entry(K, V)?
private def delete_impl(key : K) : Entry(K, V)?
# Empty hash table, nothing to do
if @indices_size_pow2 == 0
return nil
Expand Down Expand Up @@ -465,7 +465,7 @@ class Hash(K, V)
end

# Finds an entry with the given key.
protected def find_entry(key) : Entry(K, V)?
protected def find_entry(key : K) : Entry(K, V)?
# Empty hash table so there's no way it's there
if @indices_size_pow2 == 0
return nil
Expand Down Expand Up @@ -501,7 +501,7 @@ class Hash(K, V)
end

# Finds an Entry with the given key by doing a linear scan.
private def find_entry_linear_scan(key) : Entry(K, V)?
private def find_entry_linear_scan(key : K) : Entry(K, V)?
# If we have less than 8 elements we avoid computing the hash
# code and directly compare the keys (might be cheaper than
# computing a hash code of a complex structure).
Expand Down Expand Up @@ -902,7 +902,7 @@ class Hash(K, V)
end

# Computes the hash of a key.
private def key_hash(key)
private def key_hash(key : K)
if @compare_by_identity && key.responds_to?(:object_id)
hash = key.object_id.hash.to_u32!
else
Expand All @@ -911,7 +911,7 @@ class Hash(K, V)
hash == 0 ? UInt32::MAX : hash
end

private def entry_matches?(entry, hash, key)
private def entry_matches?(entry, hash, key : K)
# Tiny optimization: for these primitive types it's faster to just
# compare the key instead of comparing the hash and the key.
# We still have to skip hashes with value 0 (means deleted).
Expand All @@ -927,7 +927,7 @@ class Hash(K, V)
{% end %}
end

private def entry_matches?(entry, key)
private def entry_matches?(entry : Entry(K, V), key : K)
entry_key = entry.key

if @compare_by_identity
Expand Down Expand Up @@ -1022,7 +1022,7 @@ class Hash(K, V)
# h = Hash(String, String).new
# h["foo"] # raises KeyError
# ```
def [](key)
def [](key : K)
fetch(key) do
if (block = @block) && key.is_a?(K)
Comment thread
jgaskins marked this conversation as resolved.
Outdated
block.call(self, key.as(K))
Expand All @@ -1043,7 +1043,7 @@ class Hash(K, V)
# h = Hash(String, String).new("bar")
# h["foo"]? # => nil
# ```
def []?(key)
def []?(key : K)
fetch(key, nil)
end

Expand Down Expand Up @@ -1093,7 +1093,7 @@ class Hash(K, V)
# h.has_key?("foo") # => true
# h.has_key?("bar") # => false
# ```
def has_key?(key)
def has_key?(key : K)
!!find_entry(key)
end

Expand All @@ -1104,7 +1104,7 @@ class Hash(K, V)
# h.has_value?("foo") # => false
# h.has_value?("bar") # => true
# ```
def has_value?(val)
def has_value?(val : V)
each_value do |value|
return true if value == val
end
Expand All @@ -1119,7 +1119,7 @@ class Hash(K, V)
# h.fetch("foo", "foo") # => "bar"
# h.fetch("bar", "foo") # => "foo"
# ```
def fetch(key, default)
def fetch(key : K, default)
fetch(key) { default }
end

Expand All @@ -1131,7 +1131,7 @@ class Hash(K, V)
# h.fetch("bar") { "default value" } # => "default value"
# h.fetch("bar") { |key| key.upcase } # => "BAR"
# ```
def fetch(key)
def fetch(key : K)
entry = find_entry(key)
entry ? entry.value : yield key
end
Expand Down Expand Up @@ -1752,8 +1752,12 @@ class Hash(K, V)
self
end

# Compares with *other*. Returns `true` if all key-value pairs are the same.
def ==(other : Hash)
false
Comment thread
jgaskins marked this conversation as resolved.
Outdated
end

# Compares with *other*. Returns `true` if all key-value pairs are the same.
def ==(other : self)
return false unless size == other.size
each do |key, value|
entry = other.find_entry(key)
Expand Down
2 changes: 1 addition & 1 deletion src/mime.cr
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ module MIME
# If the same extension had a different type registered before, it needs to
# be removed from the extensions list.
if previous_type = @@types[extension]?
if extensions = @@extensions[parse_media_type(previous_type)]?
if (parsed_type = parse_media_type(previous_type)) && (extensions = @@extensions[parsed_type]?)
extensions.delete(extension)
end
end
Expand Down
10 changes: 8 additions & 2 deletions src/named_tuple.cr
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,21 @@ struct NamedTuple
#
# speak_about(**{thing: String, n: Int64}.from(hash)) # => "I see 2 worlds"
# ```
def from(hash : Hash)
def from(hash : Hash(K, V)) forall K, V
if size != hash.size
raise ArgumentError.new("Expected a hash with #{size} keys but one with #{hash.size} keys was given.")
end

{% begin %}
NamedTuple.new(
{% for key, value in T %}
{{key.stringify}}: self[{{key.symbolize}}].cast(hash.fetch({{key.symbolize}}) { hash["{{key}}"] }),
{% if K == String %}
{{key.stringify}}: self[{{key.symbolize}}].cast(hash[{{key.stringify}}]),
{% elsif K == Symbol %}
{{key.stringify}}: self[{{key.symbolize}}].cast(hash[{{key.symbolize}}]),
{% else %}
{% raise "Hash keys must be String or Symbol to convert into a NamedTuple" %}
Comment thread
jgaskins marked this conversation as resolved.
Outdated
{% end %}
{% end %}
)
{% end %}
Expand Down
10 changes: 5 additions & 5 deletions src/regex/match_data.cr
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ class Regex

caps = [] of String?
(1...size).each do |i|
caps << self[i]? unless name_table.has_key? i
caps << self[i]? unless name_table.has_key? i.to_u16
end

caps
Expand All @@ -276,7 +276,7 @@ class Regex

caps = {} of String => String?
(1...size).each do |i|
if (name = name_table[i]?) && !caps.has_key?(name)
if (name = name_table[i.to_u16]?) && !caps.has_key?(name)
caps[name] = self[name]?
end
end
Expand Down Expand Up @@ -315,7 +315,7 @@ class Regex

hash = {} of (String | Int32) => String?
(0...size).each do |i|
if name = name_table[i]?
if name = name_table[i.to_u16]?
hash[name] = self[name]? unless hash.has_key?(name)
else
hash[i] = self[i]?
Expand All @@ -334,7 +334,7 @@ class Regex

io << "Regex::MatchData("
size.times do |i|
io << ' ' << name_table.fetch(i, i) << ':' if i > 0
io << ' ' << name_table.fetch(i.to_u16, i) << ':' if i > 0
self[i]?.inspect(io)
end
io << ')'
Expand All @@ -350,7 +350,7 @@ class Regex
if i == 0
self[i].pretty_print pp
else
pp.text "#{name_table.fetch(i, i)}:"
pp.text "#{name_table.fetch(i.to_u16, i)}:"
pp.nest do
pp.breakable ""
self[i]?.pretty_print pp
Expand Down
4 changes: 2 additions & 2 deletions src/set.cr
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ struct Set(T)
# s.includes? 5 # => true
# s.includes? 9 # => false
# ```
def includes?(object)
def includes?(object : T)
@hash.has_key?(object)
end

Expand All @@ -144,7 +144,7 @@ struct Set(T)
# s.delete 5
# s.includes? 5 # => false
# ```
def delete(object)
def delete(object : T)
@hash.delete(object)
self
end
Expand Down
Loading