steep 1.2.0 → 1.3.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -2
  3. data/Gemfile.lock +14 -4
  4. data/Gemfile.steep +2 -2
  5. data/Gemfile.steep.lock +17 -5
  6. data/Steepfile +7 -9
  7. data/lib/steep/annotation_parser.rb +34 -28
  8. data/lib/steep/ast/annotation.rb +16 -5
  9. data/lib/steep/ast/node/type_application.rb +74 -0
  10. data/lib/steep/ast/node/type_assertion.rb +56 -0
  11. data/lib/steep/ast/types/factory.rb +5 -1
  12. data/lib/steep/diagnostic/helper.rb +2 -1
  13. data/lib/steep/diagnostic/lsp_formatter.rb +3 -1
  14. data/lib/steep/diagnostic/ruby.rb +70 -5
  15. data/lib/steep/diagnostic/signature.rb +21 -8
  16. data/lib/steep/drivers/check.rb +1 -1
  17. data/lib/steep/drivers/checkfile.rb +1 -1
  18. data/lib/steep/drivers/langserver.rb +2 -2
  19. data/lib/steep/drivers/stats.rb +1 -1
  20. data/lib/steep/drivers/watch.rb +1 -1
  21. data/lib/steep/drivers/worker.rb +0 -1
  22. data/lib/steep/server/lsp_formatter.rb +13 -3
  23. data/lib/steep/server/master.rb +4 -1
  24. data/lib/steep/server/worker_process.rb +86 -14
  25. data/lib/steep/services/hover_provider/rbs.rb +7 -7
  26. data/lib/steep/services/hover_provider/ruby.rb +19 -4
  27. data/lib/steep/services/signature_service.rb +7 -4
  28. data/lib/steep/signature/validator.rb +36 -13
  29. data/lib/steep/source.rb +189 -71
  30. data/lib/steep/type_construction.rb +232 -126
  31. data/lib/steep/type_inference/logic_type_interpreter.rb +31 -5
  32. data/lib/steep/version.rb +1 -1
  33. data/lib/steep.rb +2 -0
  34. data/rbs_collection.steep.lock.yaml +52 -11
  35. data/rbs_collection.steep.yaml +1 -1
  36. data/sig/shims/exception.rbs +4 -0
  37. data/sig/shims/parser/comment.rbs +33 -0
  38. data/sig/shims/parser.rbs +30 -2
  39. data/sig/steep/annotation_parser.rbs +59 -0
  40. data/sig/steep/ast/annotation.rbs +21 -26
  41. data/sig/steep/ast/node/type_application.rbs +31 -0
  42. data/sig/steep/ast/node/type_assertion.rbs +26 -0
  43. data/sig/steep/ast/types/factory.rbs +0 -2
  44. data/sig/steep/diagnostic/helper.rbs +9 -3
  45. data/sig/steep/diagnostic/lsp_formatter.rbs +12 -8
  46. data/sig/steep/diagnostic/ruby.rbs +62 -8
  47. data/sig/steep/diagnostic/signature.rbs +118 -85
  48. data/sig/steep/drivers/worker.rbs +11 -13
  49. data/sig/steep/range_extension.rbs +7 -0
  50. data/sig/steep/server/lsp_formatter.rbs +14 -7
  51. data/sig/steep/server/worker_process.rbs +74 -12
  52. data/sig/steep/services/hover_provider/rbs.rbs +27 -7
  53. data/sig/steep/services/hover_provider/ruby.rbs +18 -4
  54. data/sig/steep/services/hover_provider/singleton_methods.rbs +1 -1
  55. data/sig/steep/signature/validator.rbs +76 -0
  56. data/sig/steep/source.rbs +54 -30
  57. data/sig/steep/type_construction.rbs +85 -27
  58. data/sig/steep/type_inference/method_call.rbs +1 -1
  59. data/smoke/diagnostics-rbs/inherit-module.rbs +2 -0
  60. data/smoke/diagnostics-rbs/test_expectations.yml +12 -0
  61. data/steep.gemspec +6 -1
  62. metadata +86 -6
@@ -52,10 +52,18 @@ module Steep
52
52
  context.module_context
53
53
  end
54
54
 
55
+ def module_context!
56
+ module_context or raise
57
+ end
58
+
55
59
  def method_context
56
60
  context.method_context
57
61
  end
58
62
 
63
+ def method_context!
64
+ method_context or raise
65
+ end
66
+
59
67
  def block_context
60
68
  context.block_context
61
69
  end
@@ -798,42 +806,6 @@ module Steep
798
806
  end
799
807
  end
800
808
 
801
- when :send
802
- yield_self do
803
- if self_class?(node)
804
- module_type = expand_alias(module_context.module_type)
805
- type = if module_type.is_a?(AST::Types::Name::Singleton)
806
- AST::Types::Name::Singleton.new(name: module_type.name)
807
- else
808
- module_type
809
- end
810
-
811
- add_typing(node, type: type)
812
- else
813
- type_send(node, send_node: node, block_params: nil, block_body: nil)
814
- end
815
- end
816
-
817
- when :csend
818
- yield_self do
819
- send_type, constr =
820
- if self_class?(node)
821
- module_type = expand_alias(module_context.module_type)
822
- type = if module_type.is_a?(AST::Types::Name::Singleton)
823
- AST::Types::Name::Singleton.new(name: module_type.name)
824
- else
825
- module_type
826
- end
827
- add_typing(node, type: type).to_ary
828
- else
829
- type_send(node, send_node: node, block_params: nil, block_body: nil, unwrap: true).to_ary
830
- end
831
-
832
- constr
833
- .update_type_env { context.type_env.join(constr.context.type_env, context.type_env) }
834
- .add_typing(node, type: union_type(send_type, AST::Builtin.nil_type))
835
- end
836
-
837
809
  when :match_with_lvasgn
838
810
  each_child_node(node) do |child|
839
811
  synthesize(child)
@@ -907,14 +879,16 @@ module Steep
907
879
  }
908
880
  )
909
881
 
910
- call, constr = type_method_call(node,
911
- receiver_type: self_type,
912
- method_name: method_context.name,
913
- method: super_method,
914
- arguments: node.children,
915
- block_params: nil,
916
- block_body: nil,
917
- topdown_hint: true)
882
+ call, constr = type_method_call(
883
+ node,
884
+ receiver_type: self_type,
885
+ method_name: method_context.name,
886
+ method: super_method,
887
+ arguments: node.children,
888
+ block_params: nil,
889
+ block_body: nil,
890
+ tapp: nil
891
+ )
918
892
 
919
893
  if call && constr
920
894
  constr.add_call(call)
@@ -947,35 +921,6 @@ module Steep
947
921
  end
948
922
  end
949
923
 
950
- when :block
951
- yield_self do
952
- send_node, params, body = node.children
953
- if send_node.type == :lambda
954
- type_lambda(node, params_node: params, body_node: body, type_hint: hint)
955
- else
956
- type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend)
957
- end
958
- end
959
-
960
- when :numblock
961
- yield_self do
962
- send_node, max_num, body = node.children
963
-
964
- if max_num == 1
965
- arg_nodes = [Parser::AST::Node.new(:procarg0, [:_1])]
966
- else
967
- arg_nodes = max_num.times.map {|i| Parser::AST::Node.new(:arg, [:"_#{i+1}"]) }
968
- end
969
-
970
- params = Parser::AST::Node.new(:args, arg_nodes)
971
-
972
- if send_node.type == :lambda
973
- type_lambda(node, params_node: params, body_node: body, type_hint: hint)
974
- else
975
- type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend)
976
- end
977
- end
978
-
979
924
  when :def
980
925
  yield_self do
981
926
  name, args_node, body_node = node.children
@@ -1547,9 +1492,9 @@ module Steep
1547
1492
 
1548
1493
  constructor.synthesize(node.children[1]) if node.children[1]
1549
1494
 
1550
- if constructor.module_context.instance_definition && module_context.module_definition
1551
- if constructor.module_context.instance_definition.type_name == module_context.module_definition.type_name
1552
- module_context.defined_module_methods.merge(constructor.module_context.defined_instance_methods)
1495
+ if constructor.module_context!.instance_definition && module_context!.module_definition
1496
+ if constructor.module_context!.instance_definition.type_name == module_context!.module_definition.type_name
1497
+ module_context!.defined_module_methods.merge(constructor.module_context!.defined_instance_methods)
1553
1498
  end
1554
1499
  end
1555
1500
  end
@@ -2446,6 +2391,41 @@ module Steep
2446
2391
 
2447
2392
  add_typing node, type: AST::Builtin.any_type, constr: constr
2448
2393
 
2394
+ when :assertion
2395
+ yield_self do
2396
+ # @type var as_type: AST::Node::TypeAssertion
2397
+ asserted_node, as_type = node.children
2398
+
2399
+ if type = as_type.type?(module_context!.nesting, checker.factory, [])
2400
+ actual_type, constr = synthesize(asserted_node, hint: type)
2401
+
2402
+ if result = no_subtyping?(sub_type: type, super_type: actual_type)
2403
+ typing.add_error(
2404
+ Diagnostic::Ruby::FalseAssertion.new(
2405
+ node: node,
2406
+ assertion_type: type,
2407
+ node_type: actual_type
2408
+ )
2409
+ )
2410
+ end
2411
+
2412
+ constr.add_typing(node, type: type)
2413
+ else
2414
+ synthesize(asserted_node, hint: hint)
2415
+ end
2416
+ end
2417
+
2418
+ when :block, :numblock, :send, :csend
2419
+ synthesize_sendish(node, hint: hint, tapp: nil)
2420
+
2421
+ when :tapp
2422
+ yield_self do
2423
+ sendish, tapp = node.children
2424
+ type, constr = synthesize_sendish(sendish, hint: hint, tapp: tapp)
2425
+
2426
+ constr.add_typing(node, type: type)
2427
+ end
2428
+
2449
2429
  else
2450
2430
  typing.add_error(Diagnostic::Ruby::UnsupportedSyntax.new(node: node))
2451
2431
  add_typing(node, type: AST::Builtin.any_type)
@@ -2481,6 +2461,74 @@ module Steep
2481
2461
  end
2482
2462
  end
2483
2463
 
2464
+ def synthesize_sendish(node, hint:, tapp:)
2465
+ case node.type
2466
+ when :send
2467
+ yield_self do
2468
+ if self_class?(node)
2469
+ module_type = expand_alias(module_context!.module_type)
2470
+ type = if module_type.is_a?(AST::Types::Name::Singleton)
2471
+ AST::Types::Name::Singleton.new(name: module_type.name)
2472
+ else
2473
+ module_type
2474
+ end
2475
+
2476
+ add_typing(node, type: type)
2477
+ else
2478
+ type_send(node, send_node: node, block_params: nil, block_body: nil, tapp: tapp)
2479
+ end
2480
+ end
2481
+ when :csend
2482
+ yield_self do
2483
+ send_type, constr =
2484
+ if self_class?(node)
2485
+ module_type = expand_alias(module_context!.module_type)
2486
+ type = if module_type.is_a?(AST::Types::Name::Singleton)
2487
+ AST::Types::Name::Singleton.new(name: module_type.name)
2488
+ else
2489
+ module_type
2490
+ end
2491
+ add_typing(node, type: type).to_ary
2492
+ else
2493
+ type_send(node, send_node: node, block_params: nil, block_body: nil, unwrap: true, tapp: tapp).to_ary
2494
+ end
2495
+
2496
+ constr
2497
+ .update_type_env { context.type_env.join(constr.context.type_env, context.type_env) }
2498
+ .add_typing(node, type: union_type(send_type, AST::Builtin.nil_type))
2499
+ end
2500
+ when :block
2501
+ yield_self do
2502
+ send_node, params, body = node.children
2503
+ if send_node.type == :lambda
2504
+ type_lambda(node, params_node: params, body_node: body, type_hint: hint)
2505
+ else
2506
+ type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend, tapp: tapp)
2507
+ end
2508
+ end
2509
+ when :numblock
2510
+ yield_self do
2511
+ send_node, max_num, body = node.children
2512
+
2513
+ if max_num == 1
2514
+ arg_nodes = [Parser::AST::Node.new(:procarg0, [:_1])]
2515
+ else
2516
+ arg_nodes = max_num.times.map {|i| Parser::AST::Node.new(:arg, [:"_#{i+1}"]) }
2517
+ end
2518
+
2519
+ params = Parser::AST::Node.new(:args, arg_nodes)
2520
+
2521
+ if send_node.type == :lambda
2522
+ type_lambda(node, params_node: params, body_node: body, type_hint: hint)
2523
+ else
2524
+ type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend, tapp: tapp)
2525
+ end
2526
+ end
2527
+ else
2528
+ raise "Unexpected node is given to `#synthesize_sendish` (#{node.type}, #{node.location.first_line})"
2529
+ end
2530
+ end
2531
+
2484
2532
  def masgn_lhs?(lhs)
2485
2533
  lhs.children.all? do |a|
2486
2534
  asgn_type = if a.type == :splat
@@ -2833,6 +2881,7 @@ module Steep
2833
2881
  def synthesize_children(node, skips: [])
2834
2882
  skips = Set.new.compare_by_identity.merge(skips)
2835
2883
 
2884
+ # @type var constr: TypeConstruction
2836
2885
  constr = self
2837
2886
 
2838
2887
  each_child_node(node) do |child|
@@ -2858,18 +2907,20 @@ module Steep
2858
2907
  end
2859
2908
  end
2860
2909
 
2861
- def type_send_interface(node, interface:, receiver:, receiver_type:, method_name:, arguments:, block_params:, block_body:)
2910
+ def type_send_interface(node, interface:, receiver:, receiver_type:, method_name:, arguments:, block_params:, block_body:, tapp:)
2862
2911
  method = interface&.methods&.[](method_name)
2863
2912
 
2864
2913
  if method
2865
- call, constr = type_method_call(node,
2866
- method: method,
2867
- method_name: method_name,
2868
- arguments: arguments,
2869
- block_params: block_params,
2870
- block_body: block_body,
2871
- receiver_type: receiver_type,
2872
- topdown_hint: true)
2914
+ call, constr = type_method_call(
2915
+ node,
2916
+ method: method,
2917
+ method_name: method_name,
2918
+ arguments: arguments,
2919
+ block_params: block_params,
2920
+ block_body: block_body,
2921
+ receiver_type: receiver_type,
2922
+ tapp: tapp
2923
+ )
2873
2924
 
2874
2925
  if call && constr
2875
2926
  case method_name.to_s
@@ -2962,7 +3013,7 @@ module Steep
2962
3013
  send_node = node.children[0]
2963
3014
  case send_node.type
2964
3015
  when :super, :zsuper
2965
- method_name = method_context.name
3016
+ method_name = method_context!.name or raise
2966
3017
  return fallback_to_any(send_node) do
2967
3018
  Diagnostic::Ruby::UnexpectedSuper.new(node: send_node, method: method_name)
2968
3019
  end
@@ -2981,8 +3032,9 @@ module Steep
2981
3032
  end
2982
3033
  end
2983
3034
 
2984
- def type_send(node, send_node:, block_params:, block_body:, unwrap: false)
3035
+ def type_send(node, send_node:, block_params:, block_body:, unwrap: false, tapp:)
2985
3036
  # @type var constr: TypeConstruction
3037
+ # @type var receiver: Parser::AST::Node?
2986
3038
 
2987
3039
  case send_node.type
2988
3040
  when :super, :zsuper
@@ -3042,7 +3094,8 @@ module Steep
3042
3094
  method_name: method_name,
3043
3095
  arguments: arguments,
3044
3096
  block_params: block_params,
3045
- block_body: block_body
3097
+ block_body: block_body,
3098
+ tapp: tapp
3046
3099
  )
3047
3100
  else
3048
3101
  constr = constr.synthesize_children(node, skips: [receiver])
@@ -3064,8 +3117,8 @@ module Steep
3064
3117
  def builder_config
3065
3118
  Interface::Builder::Config.new(
3066
3119
  self_type: self_type,
3067
- class_type: module_context.module_type,
3068
- instance_type: module_context.instance_type,
3120
+ class_type: module_context!.module_type,
3121
+ instance_type: module_context!.instance_type,
3069
3122
  variable_bounds: variable_context.upper_bounds
3070
3123
  )
3071
3124
  end
@@ -3113,6 +3166,7 @@ module Steep
3113
3166
  # compact
3114
3167
  return_type = method_type.type.return_type
3115
3168
  if AST::Builtin::Array.instance_type?(return_type)
3169
+ # @type var return_type: AST::Types::Name::Instance
3116
3170
  elem = return_type.args[0]
3117
3171
  type = AST::Builtin::Array.instance_type(unwrap(elem))
3118
3172
 
@@ -3120,7 +3174,7 @@ module Steep
3120
3174
  call = TypeInference::MethodCall::Special.new(
3121
3175
  node: node,
3122
3176
  context: constr.context.method_context,
3123
- method_name: decl.method_name,
3177
+ method_name: decl.method_name.method_name,
3124
3178
  receiver_type: receiver_type,
3125
3179
  actual_method_type: method_type.with(type: method_type.type.with(return_type: type)),
3126
3180
  return_type: type,
@@ -3135,6 +3189,7 @@ module Steep
3135
3189
  # compact
3136
3190
  return_type = method_type.type.return_type
3137
3191
  if AST::Builtin::Hash.instance_type?(return_type)
3192
+ # @type var return_type: AST::Types::Name::Instance
3138
3193
  key = return_type.args[0]
3139
3194
  value = return_type.args[1]
3140
3195
  type = AST::Builtin::Hash.instance_type(key, unwrap(value))
@@ -3143,7 +3198,7 @@ module Steep
3143
3198
  call = TypeInference::MethodCall::Special.new(
3144
3199
  node: node,
3145
3200
  context: constr.context.method_context,
3146
- method_name: decl.method_name,
3201
+ method_name: decl.method_name.method_name,
3147
3202
  receiver_type: receiver_type,
3148
3203
  actual_method_type: method_type.with(type: method_type.type.with(return_type: type)),
3149
3204
  return_type: type,
@@ -3158,7 +3213,7 @@ module Steep
3158
3213
  nil
3159
3214
  end
3160
3215
 
3161
- def type_method_call(node, method_name:, receiver_type:, method:, arguments:, block_params:, block_body:, topdown_hint:)
3216
+ def type_method_call(node, method_name:, receiver_type:, method:, arguments:, block_params:, block_body:, tapp:)
3162
3217
  node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
3163
3218
 
3164
3219
  results = method.method_types.map do |method_type|
@@ -3182,39 +3237,26 @@ module Steep
3182
3237
  arguments: arguments,
3183
3238
  block_params: block_params,
3184
3239
  block_body: block_body,
3185
- topdown_hint: topdown_hint
3240
+ tapp: tapp
3186
3241
  )
3187
3242
  end
3188
3243
  end
3189
3244
  end
3190
3245
 
3191
3246
  case
3192
- when results.empty?
3193
- method_type = method.method_types.last
3194
- all_decls = method.method_types.each.with_object(Set[]) do |method_type, set|
3195
- set.merge(method_type.method_decls)
3196
- end
3197
-
3198
- error = Diagnostic::Ruby::IncompatibleArguments.new(node: node, method_name: method_name, receiver_type: receiver_type, method_types: method.method_types)
3199
- call = TypeInference::MethodCall::Error.new(
3200
- node: node,
3201
- context: context.method_context,
3202
- method_name: method_name,
3203
- receiver_type: receiver_type,
3204
- return_type: method_type.type.return_type,
3205
- errors: [error],
3206
- method_decls: all_decls
3207
- )
3208
- constr = self.with_new_typing(typing.new_child(node_range))
3247
+ when results.one?
3248
+ # There is only one overload, use the type checking result
3249
+ call, constr = results[0]
3209
3250
  when (call, constr = results.find {|call, _| call.is_a?(TypeInference::MethodCall::Typed) })
3210
- # Nop
3251
+ # Successfully type checked with one of the overloads
3211
3252
  else
3212
- if results.one?
3213
- call, constr = results[0]
3214
- else
3215
- return
3216
- end
3253
+ # No suitable overload, more than one overlodas
3254
+ return
3217
3255
  end
3256
+
3257
+ constr or raise
3258
+ call or raise
3259
+
3218
3260
  constr.typing.save!
3219
3261
 
3220
3262
  [
@@ -3367,12 +3409,78 @@ module Steep
3367
3409
  constr
3368
3410
  end
3369
3411
 
3370
- def try_method_type(node, receiver_type:, method_name:, method_type:, arguments:, block_params:, block_body:, topdown_hint:)
3371
- type_params, instantiation = Interface::TypeParam.rename(method_type.type_params)
3372
- type_param_names = type_params.map(&:name)
3373
-
3412
+ def try_method_type(node, receiver_type:, method_name:, method_type:, arguments:, block_params:, block_body:, tapp:)
3374
3413
  constr = self
3375
3414
 
3415
+ if tapp && type_args = tapp.types?(module_context!.nesting, checker.factory, [])
3416
+ type_arity = method_type.type_params.size
3417
+ type_param_names = method_type.type_params.map(&:name)
3418
+
3419
+ # Explicit type application
3420
+ if type_args.size == type_arity
3421
+ # @type var args_: Array[AST::Types::t]
3422
+ args_ = []
3423
+
3424
+ type_args.each_with_index do |type, index|
3425
+ param = method_type.type_params[index]
3426
+ if param.upper_bound
3427
+ if result = no_subtyping?(sub_type: type, super_type: param.upper_bound)
3428
+ args_ << AST::Builtin.any_type
3429
+ constr.typing.add_error(
3430
+ Diagnostic::Ruby::TypeArgumentMismatchError.new(
3431
+ type_arg: type,
3432
+ type_param: param,
3433
+ result: result
3434
+ )
3435
+ )
3436
+ else
3437
+ args_ << type
3438
+ end
3439
+ else
3440
+ args_ << type
3441
+ end
3442
+ end
3443
+
3444
+ method_type = method_type.instantiate(Interface::Substitution.build(type_param_names, args_))
3445
+ else
3446
+ if type_args.size > type_arity
3447
+ type_args.drop(type_arity).each do |type_arg|
3448
+ constr.typing.add_error(
3449
+ Diagnostic::Ruby::UnexpectedTypeArgument.new(
3450
+ type_arg: type_arg,
3451
+ method_type: method_type
3452
+ )
3453
+ )
3454
+ end
3455
+ end
3456
+
3457
+ if type_args.size < type_arity
3458
+ constr.typing.add_error(
3459
+ Diagnostic::Ruby::InsufficientTypeArgument.new(
3460
+ node: tapp.node,
3461
+ type_args: type_args,
3462
+ method_type: method_type
3463
+ )
3464
+ )
3465
+ end
3466
+
3467
+ method_type = method_type.instantiate(
3468
+ Interface::Substitution.build(
3469
+ type_param_names,
3470
+ Array.new(type_param_names.size, AST::Builtin.any_type)
3471
+ )
3472
+ )
3473
+ end
3474
+
3475
+ type_params = []
3476
+ type_param_names.clear
3477
+ else
3478
+ # Infer type application
3479
+ type_params, instantiation = Interface::TypeParam.rename(method_type.type_params)
3480
+ type_param_names = type_params.map(&:name)
3481
+ method_type = method_type.instantiate(instantiation)
3482
+ end
3483
+
3376
3484
  constr = constr.with(
3377
3485
  context: context.with(
3378
3486
  variable_context: TypeInference::Context::TypeVariableContext.new(
@@ -3382,14 +3490,12 @@ module Steep
3382
3490
  )
3383
3491
  )
3384
3492
 
3385
- method_type = method_type.instantiate(instantiation)
3386
-
3387
3493
  variance = Subtyping::VariableVariance.from_method_type(method_type)
3388
3494
  constraints = Subtyping::Constraints.new(unknowns: type_params.map(&:name))
3389
3495
  ccontext = Subtyping::Constraints::Context.new(
3390
3496
  self_type: self_type,
3391
- instance_type: module_context.instance_type,
3392
- class_type: module_context.module_type,
3497
+ instance_type: module_context!.instance_type,
3498
+ class_type: module_context!.module_type,
3393
3499
  variance: variance
3394
3500
  )
3395
3501
 
@@ -3576,7 +3682,7 @@ module Steep
3576
3682
 
3577
3683
  case node.children[0].type
3578
3684
  when :super, :zsuper
3579
- unless method_context.super_method
3685
+ unless method_context!.super_method
3580
3686
  errors << Diagnostic::Ruby::UnexpectedSuper.new(
3581
3687
  node: node.children[0],
3582
3688
  method: method_name
@@ -134,7 +134,9 @@ module Steep
134
134
  assignments = masgn.expand(lhs, rhs_type_converted, false)
135
135
  end
136
136
 
137
- assignments or raise
137
+ unless assignments
138
+ raise "Multiple assignment rhs doesn't look correct: #{rhs_type.to_s} (#{assignment_node.location.expression&.source_line})"
139
+ end
138
140
 
139
141
  assignments.each do |pair|
140
142
  node, type = pair
@@ -373,17 +375,41 @@ module Steep
373
375
  ]
374
376
 
375
377
  else
378
+ # There are four possible relations between `type` and `instance_type`
379
+ #
380
+ # ```ruby
381
+ # case object # object: T
382
+ # when K # K: singleton(K)
383
+ # when ...
384
+ # end
385
+ # ````
386
+ #
387
+ # 1. T <: K && K <: T (T == K, T = Integer, K = Numeric)
388
+ # 2. T <: K (example: T = Integer, K = Numeric)
389
+ # 3. K <: T (example: T = Numeric, K = Integer)
390
+ # 4. none of the above (example: T = String, K = Integer)
391
+
376
392
  relation = Subtyping::Relation.new(sub_type: type, super_type: instance_type)
377
393
  if subtyping.check(relation, constraints: Subtyping::Constraints.empty, self_type: AST::Types::Self.new, instance_type: AST::Types::Instance.new, class_type: AST::Types::Class.new).success?
394
+ # 1 or 2. Satisfies the condition, no narrowing because `type` is already more specific than/equals to `instance_type`
378
395
  [
379
396
  [type],
380
397
  []
381
398
  ]
382
399
  else
383
- [
384
- [],
385
- [type]
386
- ]
400
+ if subtyping.check(relation.flip, constraints: Subtyping::Constraints.empty, self_type: AST::Types::Self.new, instance_type: AST::Types::Instance.new, class_type: AST::Types::Class.new).success?
401
+ # 3. Satisfied the condition, narrows to `instance_type`, but cannot remove it from *falsy* list
402
+ [
403
+ [instance_type],
404
+ [type]
405
+ ]
406
+ else
407
+ # 4
408
+ [
409
+ [],
410
+ [type]
411
+ ]
412
+ end
387
413
  end
388
414
  end
389
415
  end
data/lib/steep/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Steep
2
- VERSION = "1.2.0"
2
+ VERSION = "1.3.0.pre.1"
3
3
  end
data/lib/steep.rb CHANGED
@@ -50,6 +50,8 @@ require "steep/ast/types/record"
50
50
  require "steep/ast/types/logic"
51
51
  require "steep/ast/annotation"
52
52
  require "steep/ast/annotation/collection"
53
+ require "steep/ast/node/type_assertion"
54
+ require "steep/ast/node/type_application"
53
55
  require "steep/ast/builtin"
54
56
  require "steep/ast/types/factory"
55
57