emacs-elsa / Elsa

Emacs Lisp Static Analyzer and gradual type system.
GNU General Public License v3.0
640 stars 26 forks source link

Some correct code that Elsa complains about #164

Closed DarwinAwardWinner closed 1 year ago

DarwinAwardWinner commented 4 years ago

I've tried to pull out all the easily-extracted test cases from my ido-cr+ package and assemble them here. These are all things that should be correct, but Elsa doesn't like them for one reason or another.

; -*- lexical-binding: t -*-

;; This is OK
'message
;; But these are not: reference to free var "message"
#'message
(function message)

;; Elsa thinks the minor mode name is a free var
(define-minor-mode my-own-minor-mode
  "My minor mode")

;; Elsa thinks the macro name and arguments are free variables. I
;; guess it doesn't know about macros at all?
(defmacro my-macro (x) x)

;; Elsa doesn't know minibuffer-depth
(1+ (minibuffer-depth))

(defvar my-custom-var-1
  (or
   (if (memq completing-read-function
             '(ido-completing-read+
               ido-completing-read
               completing-read-ido-ubiquitous
               completing-read-ido
               ido-ubiquitous-completing-read))
       'completing-read-default
     completing-read-function)
   'completing-read-default))

(defun myfun1 (arg) arg)

;; Elsa thinks the argument's type is Unbound
(myfun1 my-custom-var-1)

(let ((my-lex-var nil))
  ;; Elsa thinks `my-lex-var' can only be nil
  (setq my-lex-var t)
  ;; Elsa thinks this conditional is always false because it thinks
  ;; the var is always nil.
  (when my-lex-var
    (message "hello"))
  my-lex-var)

(require 'cl-lib)
;; Elsa clearly knows nothing about cl loop macro
(cl-loop for x from 1 up to 10
         collect x)

;; I guess Elsa doesn't know the types of other cl-lib functions
;; either. Although maybe the problem is that the last line of
;; `cl-set-difference' is a call to `nreverse', which also doesn't
;; have type annotations.
(length (cl-set-difference '(1 2 3) '(1 2 4)))

Runing cask exec elsa on this file gives:

$ cask exec elsa elsa-doesnt-like-these.el
analyzer: updating variable my-custom-var-1, old type nil
elsa-doesnt-like-these.el:6:2:error:Reference to free variable `message'.
elsa-doesnt-like-these.el:7:10:error:Reference to free variable `message'.
elsa-doesnt-like-these.el:10:19:error:Reference to free variable `my-own-minor-mode'.
elsa-doesnt-like-these.el:15:10:error:Reference to free variable `my-macro'.
elsa-doesnt-like-these.el:15:23:error:Reference to free variable `x'.
elsa-doesnt-like-these.el:15:1:notice:Public functions should have a docstring.
elsa-doesnt-like-these.el:18:1:error:Argument 1 accepts type Number | Marker but received Mixed
elsa-doesnt-like-these.el:32:1:notice:Public functions should have a docstring.
elsa-doesnt-like-these.el:35:1:error:Argument 1 accepts type Mixed but received Unbound
elsa-doesnt-like-these.el:39:8:error:Variable my-lex-var expects Nil, got T
elsa-doesnt-like-these.el:42:8:warning:Condition always evaluates to non-nil.
elsa-doesnt-like-these.el:49:9:error:Reference to free variable `for'.
elsa-doesnt-like-these.el:49:13:error:Reference to free variable `x'.
elsa-doesnt-like-these.el:49:15:error:Reference to free variable `from'.
elsa-doesnt-like-these.el:49:22:error:Reference to free variable `up'.
elsa-doesnt-like-these.el:49:25:error:Reference to free variable `to'.
elsa-doesnt-like-these.el:50:9:error:Reference to free variable `collect'.
elsa-doesnt-like-these.el:50:17:error:Reference to free variable `x'.
elsa-doesnt-like-these.el:56:1:error:Argument 1 accepts type Sequence? but received Mixed
DarwinAwardWinner commented 4 years ago

If you can point to where these can be fixed, I can take a stab at them.

Fuco1 commented 4 years ago

By the way the type annotations in the file which you updated is only a small selection. If you look into ./dev there is a file with all the defuns from .c files, and we also need to annotate 10k or so elisp functions form the core.

I'm also slowly working on an inference engine which can figure some of it out on its own (theoretically everything should be possible to infer once all the built-ins are annotated).

I'll split this issue into multiple issues to track each one separately, they seem to be quite diverse.

Fuco1 commented 1 year ago

All the issues except the setq and lexical var are solved. The macros are discussed in #196 #205. So I'll close this issue to keep the list clean.