Skip to content
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

Compiler: raise when allocating an abstract virtual type #12141

Merged
merged 1 commit into from
Jun 28, 2022

Conversation

asterite
Copy link
Member

Fixes #3835
Fixes #12123

Consider this code:

abstract class Foo
end

class Bar < Foo
end

class Baz < Foo
end

a = [] of Foo.class

# Maybe these are read from a configuration file!
a << Bar
a << Baz

instances = a.map(&.new)

So far, so good.

The idea is to support the scenario of having an array of types, being able to fill that with some classes, and eventually instantiate them all.

The problem comes when we put a Foo in that array:

a << Foo

a.map(&.new) # Oops!

Previously, the compiler would actually create an instance of Foo, which didn't make sense because Foo is abstract.

So now in this PR when you do that, you get a runtime error when you call new on Foo when the compiler doesn't know which of the types there are there (in the hierarchy.), like in the example above.

Note that if you do:

Foo.new

the compiler absolutely knows that Foo is the receiver, and will produce a compile-time error instead.

Alternatively, we could disallow calling new on a type that's "an abstract class or any of its sublclasses" but I think that can limit some use cases or scenarios.

@straight-shoota straight-shoota added kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler:semantic labels Jun 21, 2022
@beta-ziliani beta-ziliani added this to the 1.5.0 milestone Jun 24, 2022
@cyangle
Copy link
Contributor

cyangle commented Jun 25, 2022

I managed to get a Lucky toy app running with the interpreter including code from this PR.
But I got this runtime error from the Lucky::RouteHandler:

GET /api/v1/users/718899499666702337 (85414c3b-38a9-4fdb-8681-528d4ef38f94)
 ▸  Exception 

     Can't instantiate abstract class Lucky::Action

    Backtrace 

     217:1:/home/chao/git/personal/crystal/src/raise.cr in 'raise'
     251:3:/home/chao/git/personal/crystal/src/raise.cr in 'raise'
     6:3:/home/chao/git/personal/toy/lib/lucky/src/lucky/action.cr in 'new'
     10:7:/home/chao/git/personal/toy/lib/lucky/src/lucky/route_handler.cr in 'call'
     28:7:/home/chao/git/personal/crystal/src/http/server/handler.cr in 'call_next'
     26:5:/home/chao/git/personal/toy/lib/lucky/src/lucky/remote_ip_handler.cr in 'call'
     28:7:/home/chao/git/personal/crystal/src/http/server/handler.cr in 'call_next'
     14:5:/home/chao/git/personal/toy/lib/lucky/src/lucky/error_handler.cr in 'call'
     28:7:/home/chao/git/personal/crystal/src/http/server/handler.cr in 'call_next'
     34:9:/home/chao/git/personal/toy/lib/lucky/src/lucky/log_handler.cr in 'call'
     356:5:/home/chao/git/personal/crystal/src/time.cr in 'measure'
     33:18:/home/chao/git/personal/toy/lib/lucky/src/lucky/log_handler.cr in 'call'
     28:7:/home/chao/git/personal/crystal/src/http/server/handler.cr in 'call_next'
     11:5:/home/chao/git/personal/toy/lib/lucky/src/lucky/http_method_override_handler.cr in 'call'
     28:7:/home/chao/git/personal/crystal/src/http/server/handler.cr in 'call_next'
     37:7:/home/chao/git/personal/toy/lib/lucky/src/lucky/force_ssl_handler.cr in 'call'
     28:7:/home/chao/git/personal/crystal/src/http/server/handler.cr in 'call_next'
     24:5:/home/chao/git/personal/toy/lib/lucky/src/lucky/request_id_handler.cr in 'call'
     51:11:/home/chao/git/personal/crystal/src/http/server/request_processor.cr in 'process'
     120:7:/home/chao/git/personal/crystal/src/log/main.cr in 'with_context'
     100:7:/home/chao/git/personal/crystal/src/log/main.cr in 'with_context'
     119:5:/home/chao/git/personal/crystal/src/log/main.cr in 'with_context'
     50:9:/home/chao/git/personal/crystal/src/http/server/request_processor.cr in 'process'
     515:5:/home/chao/git/personal/crystal/src/http/server.cr in 'handle_client'
     99:1:/home/chao/git/personal/crystal/src/concurrent.cr in '->'
     146:5:/home/chao/git/personal/crystal/src/fiber.cr in 'run'
     98:34:/home/chao/git/personal/crystal/src/fiber.cr in '->'

 ▸ Sent 500 Internal Server Error (179.23ms) (85414c3b-38a9-4fdb-8681-528d4ef38f94)

I also tried the compiled version and it worked without this problem.
Anyway, this is still a big step forward since the interpreter raises error without this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler:semantic
Projects
None yet
5 participants