Skip to content

Commit

Permalink
Revert: Don't automatically virtualize two types in the same hierarch…
Browse files Browse the repository at this point in the history
…y, unless one is deeper than the other
  • Loading branch information
asterite committed Jul 7, 2018
1 parent fa8a586 commit fb4f380
Show file tree
Hide file tree
Showing 13 changed files with 23 additions and 54 deletions.
2 changes: 1 addition & 1 deletion samples/sdl/fire.cr
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ point_count = ARGV.size > 0 ? ARGV[0].to_i : 4
yellow = YellowColorPattern.new
magenta = MagentaColorPattern.new
cyan = CyanColorPattern.new
rainbow = RainbowColorPattern.new [yellow, magenta, cyan] of ColorPattern
rainbow = RainbowColorPattern.new [yellow, magenta, cyan]

main_points = [] of MainPoint
main_points << MainPoint.new(50, 50, -Math::PI / 8, 1.4, yellow)
Expand Down
10 changes: 1 addition & 9 deletions spec/compiler/codegen/class_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -504,15 +504,7 @@ describe "Code gen: class" do

it "does to_s for virtual metaclass type (3)" do
run(%(
class Class
def name : String
{{ @type.name.stringify }}
end
def to_s
name
end
end
require "prelude"
class Foo; end
class Bar < Foo; end
Expand Down
13 changes: 2 additions & 11 deletions spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,7 @@ private def it_parses(string, expected_node, file = __FILE__, line = __LINE__)
parser = Parser.new(string)
parser.filename = "/foo/bar/baz.cr"
node = parser.parse

# If it's an Array, map it all to ASTNode (the array might be of a
# union that's not exactly ASTNode). Not having to write `[...] of ASTNode`
# simplifies testing a bit.
local_expected_node = expected_node
if local_expected_node.is_a?(Array)
local_expected_node = local_expected_node.map(&.as(ASTNode))
end

node.should eq(Expressions.from(local_expected_node))
node.should eq(Expressions.from expected_node)
end
end

Expand Down Expand Up @@ -992,7 +983,7 @@ module Crystal
it_parses "def foo(x); end; x", [Def.new("foo", ["x".arg]), "x".call]
it_parses "def foo; / /; end", Def.new("foo", body: regex(" "))

it_parses "\"foo\#{bar}baz\"", StringInterpolation.new(["foo".string, "bar".call, "baz".string] of ASTNode)
it_parses "\"foo\#{bar}baz\"", StringInterpolation.new(["foo".string, "bar".call, "baz".string])
it_parses "qux \"foo\#{bar do end}baz\"", Call.new(nil, "qux", StringInterpolation.new(["foo".string, Call.new(nil, "bar", block: Block.new), "baz".string] of ASTNode))
it_parses "\"\#{1\n}\"", StringInterpolation.new([1.int32] of ASTNode)

Expand Down
2 changes: 1 addition & 1 deletion spec/compiler/semantic/class_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ describe "Semantic: class" do
end
a = Bar.new || Baz.new
") { union_of types["Bar"], types["Baz"] }
") { types["Foo"].virtual_type }
end

it "types class and subclass as one type" do
Expand Down
4 changes: 2 additions & 2 deletions spec/compiler/semantic/def_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ describe "Semantic: def" do

it "says compile-time type on error" do
assert_error %(
class Foo
abstract class Foo
end
class Bar < Foo
Expand All @@ -328,7 +328,7 @@ describe "Semantic: def" do
class Baz < Foo
end
f = Bar.new || Foo.new
f = Bar.new || Baz.new
f.bar
),
"compile-time type is Foo+"
Expand Down
2 changes: 1 addition & 1 deletion spec/compiler/semantic/struct_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe "Semantic: struct" do
struct Baz < Foo
end
(Bar.new || Baz.new).as(Foo)
Bar.new || Baz.new
") { types["Foo"].virtual_type! }
end

Expand Down
4 changes: 2 additions & 2 deletions spec/compiler/semantic/virtual_metaclass_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe "Semantic: virtual metaclass" do

it "allows allocating virtual type when base class is abstract" do
assert_type("
class Foo
abstract class Foo
end
class Bar < Foo
Expand All @@ -44,7 +44,7 @@ describe "Semantic: virtual metaclass" do
class Baz < Foo
end
bar = Bar.new || Foo.new
bar = Bar.new || Baz.new
baz = bar.class.allocate
") { types["Foo"].virtual_type }
end
Expand Down
2 changes: 1 addition & 1 deletion spec/compiler/semantic/virtual_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ describe "Semantic: virtual" do
end
a = Bar.new || Baz.new
") { union_of types["Bar"], types["Baz"] }
") { types["Foo"].virtual_type }
end

it "types class and two subclasses" do
Expand Down
5 changes: 0 additions & 5 deletions src/compiler/crystal/codegen/cast.cr
Original file line number Diff line number Diff line change
Expand Up @@ -544,11 +544,6 @@ class Crystal::CodeGenVisitor
end

def upcast_distinct(value, to_type : MetaclassType | GenericClassInstanceMetaclassType | GenericModuleInstanceMetaclassType | VirtualMetaclassType, from_type)
# Special case: union of metaclasses is still represented as a union
if from_type.is_a?(MixedUnionType)
return load(union_type_id(value))
end

value
end

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/crystal/semantic/literal_expander.cr
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ module Crystal
exps = Array(ASTNode).new(node.entries.size + 2)
exps << Assign.new(temp_var.clone, constructor).at(node)
node.entries.each do |entry|
exps << Call.new(temp_var.clone, "[]=", [entry.key.clone, entry.value.clone] of ASTNode).at(node)
exps << Call.new(temp_var.clone, "[]=", [entry.key.clone, entry.value.clone]).at(node)
end
exps << temp_var.clone

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

# (1); (4)
if assign
Expressions.new([assign, call] of ASTNode).at(node)
Expressions.new([assign, call]).at(node)
else
call
end
Expand Down
25 changes: 8 additions & 17 deletions src/compiler/crystal/semantic/type_merge.cr
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,6 @@ module Crystal
end

def type_combine(types)
# Modules and types at a higher level in the hierarchy are the ones
# that will "delete" deeper types and combine them into virtual
# types (or just modules), so we put them in the front for the algorithm.
types.sort! do |t1, t2|
if t1.module?
-1
elsif t2.module?
1
else
t1.depth <=> t2.depth
end
end

all_types = [types.shift] of Type

types.each do |t2|
Expand Down Expand Up @@ -346,10 +333,14 @@ private def class_common_ancestor(t1, t2)
return t1
end

# If one type is deeper than the other, check if going up we find
# the one in the top, and if so we combine them.
# But if they are at the same depth we don't go up.
if t1.depth > t2.depth
if t1.depth == t2.depth
t1_superclass = t1.superclass
t2_superclass = t2.superclass

if t1_superclass && t2_superclass
return t1_superclass.common_ancestor(t2_superclass)
end
elsif t1.depth > t2.depth
t1_superclass = t1.superclass
if t1_superclass
return t1_superclass.common_ancestor(t2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@ module Crystal

def transform(node : MultiAssign)
node.values = if node.values.size == 1
[instrument(node.values[0])] of ASTNode
[instrument(node.values[0])]
else
rhs = TupleLiteral.new(node.values)
rhs.location = node.location
[instrument(rhs)] of ASTNode
[instrument(rhs)]
end
node
end
Expand Down

0 comments on commit fb4f380

Please sign in to comment.