Skip to content

Commit

Permalink
Disallow typeof in type restrictions
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite authored and chris-huxtable committed Jun 6, 2018
1 parent 738c9fb commit 512fcc5
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 12 deletions.
49 changes: 41 additions & 8 deletions spec/compiler/semantic/restrictions_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,49 @@ describe "Restrictions" do
)) { types["Foo"] }
end

it "allows typeof as restriction" do
assert_type(%(
struct Int32
def self.foo(x : typeof(self))
x
end
it "errors if using typeof" do
assert_error %(
def foo(x : typeof(1))
end
Int32.foo 1
)) { int32 }
foo(1)
),
"can't use typeof in type restrictions"
end

it "errors if using typeof inside generic type" do
assert_error %(
class Gen(T)
end
def foo(x : Gen(typeof(1)))
end
foo(Gen(Int32).new)
),
"can't use typeof in type restrictions"
end

it "errors if using typeof in block restriction" do
assert_error %(
def foo(&x : typeof(1) -> )
yield 1
end
foo {}
),
"can't use 'typeof' here"
end

it "errors if using typeof in block restriction" do
assert_error %(
def foo(&x : -> typeof(1))
yield
end
foo {}
),
"can't use typeof in type restriction"
end

it "passes #278" do
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/crystal/semantic/call.cr
Original file line number Diff line number Diff line change
Expand Up @@ -941,12 +941,12 @@ class Crystal::Call

private def lookup_node_type(context, node)
bubbling_exception do
context.defining_type.lookup_type(node, self_type: context.instantiated_type.instance_type, free_vars: context.free_vars)
context.defining_type.lookup_type(node, self_type: context.instantiated_type.instance_type, free_vars: context.free_vars, allow_typeof: false)
end
end

private def lookup_node_type?(context, node)
context.defining_type.lookup_type?(node, self_type: context.instantiated_type.instance_type, free_vars: context.free_vars)
context.defining_type.lookup_type?(node, self_type: context.instantiated_type.instance_type, free_vars: context.free_vars, allow_typeof: false)
end

def bubbling_exception
Expand Down
3 changes: 1 addition & 2 deletions src/compiler/crystal/semantic/restrictions.cr
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,7 @@ module Crystal
end

def restrict(other : TypeOf, context)
lookup_type = self.lookup_type(other, self_type: context.instantiated_type.instance_type)
restrict lookup_type, context
other.raise "can't use typeof in type restrictions"
end

def restrict(other : UnionType, context)
Expand Down

0 comments on commit 512fcc5

Please sign in to comment.