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

Ruby::ArgumentTypeMismatch Cannot pass a value of type (::Type | nil) as an argument of type ::Type #1079

Closed
wilsonsilva opened this issue Mar 14, 2024 · 4 comments · Fixed by #1085
Labels
area/core Issues related to the type checker core bug
Milestone

Comments

@wilsonsilva
Copy link

wilsonsilva commented Mar 14, 2024

Problem

Steep ignores 3 nil checks on the same expression.

Offending code:

class Event
  attr_reader :pubkey
  attr_accessor :id, :sig

  def initialize(pubkey:, id: nil, sig: nil) # <--- Note that id and sig can be nil
    @pubkey = pubkey
    @id = id
    @sig = sig
  end

  def verify_signature
    return false if id.nil? || pubkey.nil? || sig.nil? # <--- Ignored by Steep

    valid_sig?(id, pubkey, sig) # <--- pubkey and sig should not be nil here. The line above ensures that
  end

  def valid_sig?(message, public_key, signature)
    true
  end
end

RBS:

class Event
  attr_reader pubkey: String
  attr_accessor id: String?  # <--- id can be nil
  attr_accessor sig: String?  # <--- sig can be nil

  def initialize: (pubkey: String, ?id: String?, ?sig: String?) -> void
  def verify_signature: -> bool
  def valid_sig?: (String, String, String) -> bool # <--- none can be nil
end

Expected behaviour

No errors should be reported by Steep. The method valid_sig? requires non-nullable arguments. And the method verify_signature ensures that the arguments id, pubkey and sig are not null before calling the method valid_sig?.

$ bundle exec steep check
# Type checking files:

.....................................................................................

No type error detected. 🫖

Actual behaviour

The following error is reported by Steep:

$ bundle exec steep check
nostr.rb:24:27: [error] Cannot pass a value of type `(::String | nil)` as an argument of type `::String`
│   (::String | nil) <: ::String
│     nil <: ::String
│
│ Diagnostic ID: Ruby::ArgumentTypeMismatch
│
└     crypto.valid_sig?(id, pubkey, sig)
                                    ~~~

Detected 1 problem from 1 file

But only when the 3 nil checks on the same expression. Fewer nil checks do not trigger the error.

Workaround

Use 2 or fewer nil checks on the same expression.

def verify_signature
  return false if id.nil? || pubkey.nil?
  return false if sig.nil?

  valid_sig?(id, pubkey, sig)
end

Steps to reproduce

  1. Clone the repo git clone git@github.com:wilsonsilva/steep-nil-argument-type-mismatch-bug.git
  2. Run bundle install
  3. Run bundle exec steep check

Environment

  • Ruby version: 3.3.0
  • Steep version: 1.6.0
  • RBS version: 3.4.4
  • OS: macOS Sonoma 14.4 (23E214)

A tiny sample project to reproduce the problem https://github.com/wilsonsilva/steep-nil-argument-type-mismatch-bug

@soutaro soutaro added bug area/core Issues related to the type checker core labels Mar 22, 2024
@soutaro soutaro added this to the Steep 1.7 milestone Mar 22, 2024
@soutaro
Copy link
Owner

soutaro commented Mar 22, 2024

Thank you for reporting the problem. Confirmed. @wilsonsilva

@soutaro
Copy link
Owner

soutaro commented Mar 24, 2024

The problem is caused because method call purity of pubkey() is omitted during type checking the || clause.

@soutaro
Copy link
Owner

soutaro commented Mar 24, 2024

Released 1.7.0.dev.3 with the fix for this problem.

@wilsonsilva
Copy link
Author

Worked like a charm. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/core Issues related to the type checker core bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants