Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0cc341dfc0fd
Choose a base ref
...
head repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: a49aef7f4526
Choose a head ref
  • 4 commits
  • 28 files changed
  • 1 contributor

Commits on Aug 10, 2016

  1. Make Indexable#unsafe_at public, but explain it's unsafe

    Ary Borenszweig committed Aug 10, 2016
    Copy the full SHA
    e077ac5 View commit details
  2. Compiler: removed MatchesLookup

    Ary Borenszweig committed Aug 10, 2016
    Copy the full SHA
    04edc81 View commit details
  3. Compiler: disallow adding methods to generic instances

    Syntax was allowed but it actually added the method to the generic type,
    not the instance.
    
    This might be allowed in the future, but right now it's better to correctly error.
    Ary Borenszweig committed Aug 10, 2016
    Copy the full SHA
    b01fc53 View commit details

Commits on Aug 11, 2016

  1. Compiler: Type refactors, docs and simplifications

    Ary Borenszweig committed Aug 11, 2016
    Copy the full SHA
    a49aef7 View commit details
2 changes: 2 additions & 0 deletions spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
@@ -1425,6 +1425,8 @@ describe "Parser" do
assert_syntax_error "require 1", "expected string literal for require"
assert_syntax_error %(def foo("bar \#{1} qux" y); y; end), "interpolation not allowed in external name"

assert_syntax_error "def Foo(Int32).bar;end"

describe "end locations" do
assert_end_location "nil"
assert_end_location "false"
21 changes: 17 additions & 4 deletions spec/compiler/semantic/def_spec.cr
Original file line number Diff line number Diff line change
@@ -195,14 +195,14 @@ describe "Semantic: def" do
assert_type("
require \"prelude\"
module MatchesLookup
module Foo
def lookup_matches(x = 1)
1
end
end
module DefContainer
include MatchesLookup
module Bar
include Foo
end
abstract class Type
@@ -212,7 +212,7 @@ describe "Semantic: def" do
end
abstract class MType < CType
include DefContainer
include Bar
end
class NonGenericMType < MType
@@ -399,4 +399,17 @@ describe "Semantic: def" do
),
"undefined constant T::String"
end

it "errors if trying to declare method on generic class instance" do
assert_error %(
class Foo(T)
end
alias Bar = Foo(Int32)
def Bar.foo
end
),
"can't define method in generic instance"
end
end
22 changes: 11 additions & 11 deletions spec/compiler/semantic/doc_spec.cr
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ describe "Semantic: doc" do
program = result.program
foo = program.types["Foo"]
foo.doc.should eq("Hello")
foo.locations.size.should eq(1)
foo.locations.not_nil!.size.should eq(1)
end

it "stores doc for abstract class" do
@@ -33,7 +33,7 @@ describe "Semantic: doc" do
program = result.program
foo = program.types["Foo"]
foo.doc.should eq("Hello")
foo.locations.size.should eq(1)
foo.locations.not_nil!.size.should eq(1)
end

it "stores doc for module" do
@@ -45,7 +45,7 @@ describe "Semantic: doc" do
program = result.program
foo = program.types["Foo"]
foo.doc.should eq("Hello")
foo.locations.size.should eq(1)
foo.locations.not_nil!.size.should eq(1)
end

it "stores doc for def" do
@@ -170,7 +170,7 @@ describe "Semantic: doc" do
program = result.program
foo = program.types["Foo"]
foo.doc.should eq("Hello")
foo.locations.size.should eq(1)
foo.locations.not_nil!.size.should eq(1)
end

it "stores doc for flags enum with base type" do
@@ -184,7 +184,7 @@ describe "Semantic: doc" do
foo = program.types["Foo"]
foo.has_attribute?("Flags").should be_true
foo.doc.should eq("Hello")
foo.locations.size.should eq(1)
foo.locations.not_nil!.size.should eq(1)
end

it "stores doc for enum and doesn't mix with value" do
@@ -198,7 +198,7 @@ describe "Semantic: doc" do
program = result.program
foo = program.types["Foo"]
foo.doc.should eq("Hello")
foo.locations.size.should eq(1)
foo.locations.not_nil!.size.should eq(1)
end

it "stores doc for enum with @[Flags]" do
@@ -224,7 +224,7 @@ describe "Semantic: doc" do
foo = program.types["Foo"]
a = foo.types["A"]
a.doc.should eq("Hello")
a.locations.size.should eq(1)
a.locations.not_nil!.size.should eq(1)
end

it "stores doc for constant" do
@@ -235,7 +235,7 @@ describe "Semantic: doc" do
program = result.program
a = program.types["A"]
a.doc.should eq("Hello")
a.locations.size.should eq(1)
a.locations.not_nil!.size.should eq(1)
end

it "stores doc for alias" do
@@ -246,7 +246,7 @@ describe "Semantic: doc" do
program = result.program
a = program.types["A"]
a.doc.should eq("Hello")
a.locations.size.should eq(1)
a.locations.not_nil!.size.should eq(1)
end

it "stores doc for nodes defined in macro call" do
@@ -304,7 +304,7 @@ describe "Semantic: doc" do
program = result.program
foo = program.types["Foo"]
foo.doc.should eq("Hello")
foo.locations.size.should eq(2)
foo.locations.not_nil!.size.should eq(2)
end

it "stores doc for module if reopening" do
@@ -328,6 +328,6 @@ describe "Semantic: doc" do
), wants_doc: true
program = result.program
foo = program.types["Foo"]
foo.locations.size.should eq(1)
foo.locations.not_nil!.size.should eq(1)
end
end
2 changes: 1 addition & 1 deletion spec/compiler/semantic/lib_spec.cr
Original file line number Diff line number Diff line change
@@ -480,7 +480,7 @@ describe "Semantic: lib" do
def LibC.foo
end
),
"can't define 'def' for lib"
"can't define method in lib LibC"
end

it "reopens lib and adds more link attributes" do
1 change: 0 additions & 1 deletion src/array.cr
Original file line number Diff line number Diff line change
@@ -496,7 +496,6 @@ class Array(T)
end
end

# :nodoc:
@[AlwaysInline]
def unsafe_at(index : Int)
@buffer[index]
1 change: 0 additions & 1 deletion src/bit_array.cr
Original file line number Diff line number Diff line change
@@ -30,7 +30,6 @@ struct BitArray
@bits = Pointer(UInt32).malloc(malloc_size, value)
end

# :nodoc:
def unsafe_at(index : Int)
bit_index, sub_index = index.divmod(32)
(@bits[bit_index] & (1 << sub_index)) > 0
10 changes: 1 addition & 9 deletions src/compiler/crystal/program.cr
Original file line number Diff line number Diff line change
@@ -20,10 +20,6 @@ module Crystal
# can also include other modules (this happens when you do `include Module`
# at the top-level).
class Program < NonGenericModuleType
include DefContainer
include DefInstanceContainer
include MatchesLookup

# All symbols (:foo, :bar) found in the program
getter symbols = Set(String).new

@@ -201,7 +197,7 @@ module Crystal
class_var_and_const_initializers << argv_unsafe

types["GC"] = gc = NonGenericModuleType.new self, self, "GC"
gc.metaclass.add_def Def.new("add_finalizer", [Arg.new("object")], Nop.new)
gc.metaclass.as(ModuleType).add_def Def.new("add_finalizer", [Arg.new("object")], Nop.new)

define_crystal_constants
end
@@ -478,10 +474,6 @@ module Crystal

# Next come overrides for the type system

def program
self
end

def metaclass
self
end
21 changes: 20 additions & 1 deletion src/compiler/crystal/semantic/ast.cr
Original file line number Diff line number Diff line change
@@ -151,6 +151,25 @@ module Crystal
end
end

# Returns the minimum and maximum number of arguments that must
# be passed to this method.
def min_max_args_sizes
max_size = args.size
default_value_index = args.index(&.default_value)
min_size = default_value_index || max_size
splat_index = self.splat_index
if splat_index
if args[splat_index].name.empty?
min_size = {default_value_index || splat_index, splat_index}.min
max_size = splat_index
else
min_size -= 1 unless default_value_index && default_value_index < splat_index
max_size = Int32::MAX
end
end
{min_size, max_size}
end

def clone_without_location
a_def = previous_def
a_def.previous = previous
@@ -530,7 +549,7 @@ module Crystal
end

class ModuleDef
property! resolved_type : Type
property! resolved_type : ModuleType
end

class LibDef
2 changes: 1 addition & 1 deletion src/compiler/crystal/semantic/call.cr
Original file line number Diff line number Diff line change
@@ -610,7 +610,7 @@ class Crystal::Call
match = Match.new(previous, arg_types, context, named_args_types)
matches = Matches.new([match] of Match, true)

unless MatchesLookup.match_def(signature, previous_item, context)
unless signature.match(previous_item, context)
raise_matches_not_found scope, previous.name, arg_types, named_args_types, matches
end

2 changes: 1 addition & 1 deletion src/compiler/crystal/semantic/call_error.cr
Original file line number Diff line number Diff line change
@@ -341,7 +341,7 @@ class Crystal::Call
signature = CallSignature.new(def_name, args.map(&.type), block, named_args_types)
defs.each do |a_def|
context = MatchContext.new(owner, a_def.owner)
match = MatchesLookup.match_def(signature, DefWithMetadata.new(a_def), context)
match = signature.match(DefWithMetadata.new(a_def), context)
next unless match

if a_def.owner == owner
2 changes: 1 addition & 1 deletion src/compiler/crystal/semantic/main_visitor.cr
Original file line number Diff line number Diff line change
@@ -2092,7 +2092,7 @@ module Crystal
when "+", "-", "*", "/", "unsafe_div"
t1 = scope.remove_typedef
t2 = typed_def.args[0].type
node.type = t1.integer? && t2.float? ? t2 : scope
node.type = t1.is_a?(IntegerType) && t2.is_a?(FloatType) ? t2 : scope
when "==", "<", "<=", ">", ">=", "!="
node.type = @program.bool
when "%", "unsafe_shl", "unsafe_shr", "|", "&", "^", "unsafe_mod"
Loading