emacs-elsa / Elsa

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

Invalid slot name: #134

Closed cpitclaudel closed 5 years ago

cpitclaudel commented 5 years ago

Hi,

This project looks great! But I can't seem to make it work. When I run it through Flycheck, I get the following error:

-*- mode: compilation; default-directory: "~/.emacs.d/lisp/fstar.el/" -*-
Compilation started at Thu Jan 10 13:42:40

cask exec elsa /home/clement/.emacs.d/lisp/fstar.el/fstar-mode.el
Invalid slot type: elsa-const-type, type, elsa-type, #s(#s(eieio--class elsa-type-string nil (#s(eieio--class elsa-type-sequence nil (#s(eieio--class elsa-type nil nil [] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data ( ...)) (elsa-const-type elsa-type-font elsa-type-overlay elsa-type-keymap elsa-type-stream elsa-type-conditionvariable elsa-type-mutex elsa-type-thread elsa-type-process elsa-type-frameconfiguration ...) nil [] [] ...)) [] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data ( ...)) (elsa-type-vector elsa-type-list elsa-type-string) nil [] [] ...)) [] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data ( ...)) (elsa-type-short-string) nil [] [] ...))

Compilation exited abnormally with code 255 at Thu Jan 10 13:42:41

I'm on GNU Linux running Emacs master (a84650334e30b2451bf4a8957bf2d57ade296d4e), and I also tried on an older version (1bc998f98f937ee82e29d80e19fda7c32632501a).

Here's a backtrace:

Debugger entered--Lisp error: (invalid-slot-type elsa-const-type type elsa-type #<elsa-type-string elsa-type-string-37df80>)
  signal(invalid-slot-type (elsa-const-type type elsa-type #<elsa-type-string elsa-type-string-37df80>))
  eieio--validate-slot-value(#s(eieio--class :name elsa-const-type :docstring nil :parents (#s(eieio--class :name elsa-type :docstring nil :parents nil :slots [] :index-table #<hash-table eq 0/65 0x4fa4a5> :children (elsa-const-type elsa-type-font elsa-type-overlay elsa-type-keymap elsa-type-stream elsa-type-conditionvariable elsa-type-mutex elsa-type-thread elsa-type-process elsa-type-frameconfiguration elsa-type-windowconfiguration elsa-type-terminal elsa-type-window elsa-type-record elsa-type-hashtable elsa-type-boolvector elsa-type-chartable elsa-generic-type elsa-function-type elsa-type-cons elsa-type-marker elsa-type-number elsa-type-frame elsa-type-buffer elsa-type-sequence elsa-type-mixed elsa-type-bool elsa-type-symbol elsa-type-nil elsa-type-t elsa-diff-type elsa-sum-type elsa-intersection-type elsa-type-empty elsa-type-unbound) :initarg-tuples nil :class-slots [] :class-allocation-values [] :default-object-cache #<elsa-type elsa-type-49725c> :options (:custom-groups nil :abstract t))) :slots [#s(cl-slot-descriptor :name type :initform unbound :type elsa-type :props nil) #s(cl-slot-descriptor :name value :initform unbound :type t :props nil)] :index-table #<hash-table eq 2/65 0x4fe425> :children nil :initarg-tuples ((:type . type) (:value . value)) :class-slots [] :class-allocation-values [] :default-object-cache #<elsa-const-type elsa-const-type-361a90> :options (:custom-groups nil)) 1 #<elsa-type-string elsa-type-string-37df80> type)
  eieio-oset(#<elsa-const-type elsa-const-type-4ec0a4> type #<elsa-type-string elsa-type-string-37df80>)
  #f(compiled-function (obj slots) "Set slots of OBJ with SLOTS which is a list of name/value pairs.\nCalled from the constructor routine." #<bytecode 0x4cc351>)(#<elsa-const-type elsa-const-type-4ec0a4> (:type #<elsa-type-string elsa-type-string-37df80> :value "Customize group for dash.el"))
  apply(#f(compiled-function (obj slots) "Set slots of OBJ with SLOTS which is a list of name/value pairs.\nCalled from the constructor routine." #<bytecode 0x4cc351>) #<elsa-const-type elsa-const-type-4ec0a4> (:type #<elsa-type-string elsa-type-string-37df80> :value "Customize group for dash.el"))
  shared-initialize(#<elsa-const-type elsa-const-type-4ec0a4> (:type #<elsa-type-string elsa-type-string-37df80> :value "Customize group for dash.el"))
  #f(compiled-function (this &optional slots) "Construct the new object THIS based on SLOTS.\nSLOTS is a tagged list where odd numbered elements are tags, and\neven numbered elements are the values to store in the tagged slot.\nIf you overload the `initialize-instance', there you will need to\ncall `shared-initialize' yourself, or you can call `call-next-method'\nto have this constructor called automatically.  If these steps are\nnot taken, then new objects of your class will not have their values\ndynamically set from SLOTS." #<bytecode 0x4cc379>)(#<elsa-const-type elsa-const-type-4ec0a4> (:type #<elsa-type-string elsa-type-string-37df80> :value "Customize group for dash.el"))
  apply(#f(compiled-function (this &optional slots) "Construct the new object THIS based on SLOTS.\nSLOTS is a tagged list where odd numbered elements are tags, and\neven numbered elements are the values to store in the tagged slot.\nIf you overload the `initialize-instance', there you will need to\ncall `shared-initialize' yourself, or you can call `call-next-method'\nto have this constructor called automatically.  If these steps are\nnot taken, then new objects of your class will not have their values\ndynamically set from SLOTS." #<bytecode 0x4cc379>) #<elsa-const-type elsa-const-type-4ec0a4> (:type #<elsa-type-string elsa-type-string-37df80> :value "Customize group for dash.el"))
  initialize-instance(#<elsa-const-type elsa-const-type-4ec0a4> (:type #<elsa-type-string elsa-type-string-37df80> :value "Customize group for dash.el"))
  #f(compiled-function (class &rest slots) "Default constructor for CLASS `eieio-default-superclass'.\nSLOTS are the initialization slots used by `initialize-instance'.\nThis static method is called when an object is constructed.\nIt allocates the vector used to represent an EIEIO object, and then\ncalls `initialize-instance' on that object." #<bytecode 0x4cc79d>)(elsa-const-type :type #<elsa-type-string elsa-type-string-37df80> :value "Customize group for dash.el")
  apply(#f(compiled-function (class &rest slots) "Default constructor for CLASS `eieio-default-superclass'.\nSLOTS are the initialization slots used by `initialize-instance'.\nThis static method is called when an object is constructed.\nIt allocates the vector used to represent an EIEIO object, and then\ncalls `initialize-instance' on that object." #<bytecode 0x4cc79d>) elsa-const-type (:type #<elsa-type-string elsa-type-string-37df80> :value "Customize group for dash.el"))
  make-instance(elsa-const-type :type #<elsa-type-string elsa-type-string-37df80> :value "Customize group for dash.el")
  apply(make-instance elsa-const-type (:type #<elsa-type-string elsa-type-string-37df80> :value "Customize group for dash.el"))
  elsa-const-type(:type #<elsa-type-string elsa-type-string-37df80> :value "Customize group for dash.el")
  elsa--read-form("Customize group for dash.el" #<elsa-state elsa-state-34a014>)
  elsa--read-form((defgroup dash nil "Customize group for dash.el" :group 'lisp :prefix "dash-") #<elsa-state elsa-state-34a014>)
  elsa-read-form(#<elsa-state elsa-state-34a014>)
  elsa-process-file("/home/clement/.emacs.d/lisp/fstar.el/.cask/27.0/elpa/dash-20180910.1856/dash.el")
  elsa--analyse:require(#<elsa-form-list elsa-form-list-544068> #<elsa-scope elsa-scope-53d0f4> #<elsa-state elsa-state-39d8fc>)
  elsa--analyse-list(#<elsa-form-list elsa-form-list-544068> #<elsa-scope elsa-scope-53d0f4> #<elsa-state elsa-state-39d8fc>)
  elsa--analyse-form(#<elsa-form-list elsa-form-list-544068> #<elsa-scope elsa-scope-53d0f4> #<elsa-state elsa-state-39d8fc>)
  elsa-analyse-form(#<elsa-state elsa-state-39d8fc> #<elsa-form-list elsa-form-list-544068>)
  elsa-process-file("fstar-mode.el")
  elsa-run()
  command-line-1(("--no-splash" "--eval" "(require 'debug)" "--eval" "(require 'help-mode)" "--eval" "(require 'cl-print)" "--eval" "(require 'cl-extra)" "--eval" "(toggle-debug-on-error)" "--eval" "(setq enable-dir-local-variables nil)" "--load=elsa" "--funcall=elsa-run" "fstar-mode.el"))
  command-line()
  normal-top-level()
Fuco1 commented 5 years ago

I think this is due to the changes in the record syntax from E25 to E26. I've recently (a week ago) finally migrated to E26 so I'm slowly fixing things. I will try to repro this.

Can you give me some minimal file that results in this error?

Are you using elsa-flycheck?

cpitclaudel commented 5 years ago

Can you give me some minimal file that results in this error?

It's not minimal, but cask exec elsa ./.cask/27.0/elpa/elsa-20190110.1457/elsa.el actually fails for me.

It seems to be due to defgroup; here's a smaller example:

$ echo "(defgroup test nil \"\" :group 'languages)" > test.el

$ cask exec elsa test.el 
Debug on Error enabled globally
Debugger entered--Lisp error: (invalid-slot-type elsa-const-type type elsa-type #<elsa-type-string elsa-type-string-37ed08>)
  signal(invalid-slot-type (elsa-const-type type elsa-type #<elsa-type-string elsa-type-string-37ed08>))
  eieio--validate-slot-value(#s(eieio--class :name elsa-const-type :docstring nil :parents (#s(eieio--class :name elsa-type :docstring nil :parents nil :slots [] :index-table #<hash-table eq 0/65 0x4fa4a5> :children (elsa-const-type elsa-type-font elsa-type-overlay elsa-type-keymap elsa-type-stream elsa-type-conditionvariable elsa-type-mutex elsa-type-thread elsa-type-process elsa-type-frameconfiguration elsa-type-windowconfiguration elsa-type-terminal elsa-type-window elsa-type-record elsa-type-hashtable elsa-type-boolvector elsa-type-chartable elsa-generic-type elsa-function-type elsa-type-cons elsa-type-marker elsa-type-number elsa-type-frame elsa-type-buffer elsa-type-sequence elsa-type-mixed elsa-type-bool elsa-type-symbol elsa-type-nil elsa-type-t elsa-diff-type elsa-sum-type elsa-intersection-type elsa-type-empty elsa-type-unbound) :initarg-tuples nil :class-slots [] :class-allocation-values [] :default-object-cache #<elsa-type elsa-type-49725c> :options (:custom-groups nil :abstract t))) :slots [#s(cl-slot-descriptor :name type :initform unbound :type elsa-type :props nil) #s(cl-slot-descriptor :name value :initform unbound :type t :props nil)] :index-table #<hash-table eq 2/65 0x4fe425> :children nil :initarg-tuples ((:type . type) (:value . value)) :class-slots [] :class-allocation-values [] :default-object-cache #<elsa-const-type elsa-const-type-361b34> :options (:custom-groups nil)) 1 #<elsa-type-string elsa-type-string-37ed08> type)
  eieio-oset(#<elsa-const-type elsa-const-type-543918> type #<elsa-type-string elsa-type-string-37ed08>)
  #f(compiled-function (obj slots) "Set slots of OBJ with SLOTS which is a list of name/value pairs.\nCalled from the constructor routine." #<bytecode 0x4cc351>)(#<elsa-const-type elsa-const-type-543918> (:type #<elsa-type-string elsa-type-string-37ed08> :value ""))
  apply(#f(compiled-function (obj slots) "Set slots of OBJ with SLOTS which is a list of name/value pairs.\nCalled from the constructor routine." #<bytecode 0x4cc351>) #<elsa-const-type elsa-const-type-543918> (:type #<elsa-type-string elsa-type-string-37ed08> :value ""))
  shared-initialize(#<elsa-const-type elsa-const-type-543918> (:type #<elsa-type-string elsa-type-string-37ed08> :value ""))
  #f(compiled-function (this &optional slots) "Construct the new object THIS based on SLOTS.\nSLOTS is a tagged list where odd numbered elements are tags, and\neven numbered elements are the values to store in the tagged slot.\nIf you overload the `initialize-instance', there you will need to\ncall `shared-initialize' yourself, or you can call `call-next-method'\nto have this constructor called automatically.  If these steps are\nnot taken, then new objects of your class will not have their values\ndynamically set from SLOTS." #<bytecode 0x4cc379>)(#<elsa-const-type elsa-const-type-543918> (:type #<elsa-type-string elsa-type-string-37ed08> :value ""))
  apply(#f(compiled-function (this &optional slots) "Construct the new object THIS based on SLOTS.\nSLOTS is a tagged list where odd numbered elements are tags, and\neven numbered elements are the values to store in the tagged slot.\nIf you overload the `initialize-instance', there you will need to\ncall `shared-initialize' yourself, or you can call `call-next-method'\nto have this constructor called automatically.  If these steps are\nnot taken, then new objects of your class will not have their values\ndynamically set from SLOTS." #<bytecode 0x4cc379>) #<elsa-const-type elsa-const-type-543918> (:type #<elsa-type-string elsa-type-string-37ed08> :value ""))
  initialize-instance(#<elsa-const-type elsa-const-type-543918> (:type #<elsa-type-string elsa-type-string-37ed08> :value ""))
  #f(compiled-function (class &rest slots) "Default constructor for CLASS `eieio-default-superclass'.\nSLOTS are the initialization slots used by `initialize-instance'.\nThis static method is called when an object is constructed.\nIt allocates the vector used to represent an EIEIO object, and then\ncalls `initialize-instance' on that object." #<bytecode 0x4cc79d>)(elsa-const-type :type #<elsa-type-string elsa-type-string-37ed08> :value "")
  apply(#f(compiled-function (class &rest slots) "Default constructor for CLASS `eieio-default-superclass'.\nSLOTS are the initialization slots used by `initialize-instance'.\nThis static method is called when an object is constructed.\nIt allocates the vector used to represent an EIEIO object, and then\ncalls `initialize-instance' on that object." #<bytecode 0x4cc79d>) elsa-const-type (:type #<elsa-type-string elsa-type-string-37ed08> :value ""))
  make-instance(elsa-const-type :type #<elsa-type-string elsa-type-string-37ed08> :value "")
  apply(make-instance elsa-const-type (:type #<elsa-type-string elsa-type-string-37ed08> :value ""))
  elsa-const-type(:type #<elsa-type-string elsa-type-string-37ed08> :value "")
  elsa--read-form("" #<elsa-state elsa-state-39ded0>)
  elsa--read-form((defgroup test nil "" :group 'languages) #<elsa-state elsa-state-39ded0>)
  elsa-read-form(#<elsa-state elsa-state-39ded0>)
  elsa-process-file("test.el")
  elsa-run()
  command-line-1(("--no-splash" "--eval" "(require 'debug)" "--eval" "(require 'help-mode)" "--eval" "(require 'cl-print)" "--eval" "(require 'cl-extra)" "--eval" "(toggle-debug-on-error)" "--eval" "(setq enable-dir-local-variables nil)" "--load=elsa" "--funcall=elsa-run" "test.el"))
  command-line()
  normal-top-level()

Are you using elsa-flycheck?

I am, but the error can be reproduced on the command line.

vermiculus commented 5 years ago

If you instead test some other expression like you tested defgroup up there, do you not get the same result?

I think this may be related to the compilation troubles.

cpitclaudel commented 5 years ago

I get different errors:

$ echo "(defun test (x y) (+ x x))" > test.el

$ cask exec elsa test.el 
Invalid slot type: elsa-form-symbol, type, elsa-type, #s(#s(eieio--class elsa-type-mixed nil (#s(eieio--class elsa-type nil nil [] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data ( ...)) (elsa-const-type elsa-type-font elsa-type-overlay elsa-type-keymap elsa-type-stream elsa-type-conditionvariable elsa-type-mutex elsa-type-thread elsa-type-process elsa-type-frameconfiguration ...) nil [] [] ...)) [] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data ( ...)) nil nil [] [] ...))

$ echo "(defvar x 1)" > test.el

$ cask exec elsa test.el 
Invalid slot type: elsa-const-type, type, elsa-type, #s(#s(eieio--class elsa-type-int nil (#s(eieio--class elsa-type-number nil (#s(eieio--class elsa-type nil nil [] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data ( ...)) (elsa-const-type elsa-type-font elsa-type-overlay elsa-type-keymap elsa-type-stream elsa-type-conditionvariable elsa-type-mutex elsa-type-thread elsa-type-process elsa-type-frameconfiguration ...) nil [] [] ...)) [] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data ( ...)) (elsa-type-float elsa-type-int) nil [] [] ...)) [] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data ( ...)) nil nil [] [] ...))
vermiculus commented 5 years ago

Definitely sounds related to #111

cpitclaudel commented 5 years ago

Interesting, thanks!

Fuco1 commented 5 years ago

Oh, this is weird...

I actually got this as well

Invalid slot type: elsa-form-symbol, type, elsa-type

but then I loaded all files and the error went away, so I thought it was just some locally broken state.

I guess I'm forgetting some require and the byte compiler in newer emacs needs the info eagerly instead of just lazily putting a symbol there expecting the stuff to be declared later (or not at all).

Fuco1 commented 5 years ago

I think it's this line

(defclass elsa-form nil
  ((start :type integer :initarg :start)
   (end :type integer :initarg :end)
   (quote-type :type symbol :initarg :quote-type :initform nil)
   (line :type integer :initarg :line)
   (column :type integer :initarg :column)
   (type :type elsa-type :initarg :type :initform (elsa-make-type Mixed)) ;;; the :type keyword here referencing `elsa-type` is prbably the problem.  If you remove that (& recompile) everything should work?
   (narrow-types :initarg :narrow-type :initform nil)
   (reachable :type trinary :initarg :reachable :initform (trinary-true))
   (parent :type (or elsa-form nil) :initarg :parent))
  :abstract t)
TatriX commented 5 years ago

I've tried "cask exec elsa pomidor.el" and got:

Invalid slot type: elsa-const-type, type, elsa-type, #s(#s(eieio--class elsa-type-string nil (#s(eieio--class elsa-type-sequence nil (#s(eieio--class elsa-type nil nil [] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data ( ...)) (elsa-const-type elsa-type-font elsa-type-overlay elsa-type-keymap elsa-type-stream elsa-type-conditionvariable elsa-type-mutex elsa-type-thread elsa-type-process elsa-type-frameconfiguration ...) nil [] [] ...)) [] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data ( ...)) (elsa-type-vector elsa-type-list elsa-type-string) nil [] [] ...)) [] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data ( ...)) (elsa-type-short-string) nil [] [] ...))

with GNU Emacs 27.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.5) of 2019-02-26

Fuco1 commented 5 years ago

I still have no idea where this comes from. The solution is to remove compiled files from your installation (either cask or package.el or anything else you are using).

This is super annoying and makes for a shitty user experience. I seriously need to look into this.

TatriX commented 5 years ago

Could you please clarify what compiled files should I remove?

Fuco1 commented 5 years ago

@TatriX actually I think I've found and fixed the problem.

I've pushed a fix to master so you can either pull from there or wait for MELPA to rebuild (takes anywhere from a couple minutes to 4 hours).

TatriX commented 5 years ago

I've got the latest version from git, did cask link elsa ~/.emacs.d/Elsa again and now I'm getting:

Invalid read syntax: "."
Fuco1 commented 5 years ago

I've grabbed pomidor.el from the repo, latest master. Works for me. Make sure to remove all traces of the old elsa code (do a find for elsa in your projects, cask directories etc...)

The analysis output is here: https://gist.github.com/Fuco1/7db8be3706e646bab70e786d50970e65

TatriX commented 5 years ago

I removed git-cloned version in favor of (depends-on "elsa"). That's what I'm getting now:

$ cask exec elsa pomidor.el
analyzer: updating variable log4e-log-level-alist, old type nil
analyzer: updating variable log4e-default-logging-function-name-alist, old type nil
analyzer: updating variable log4e--regexp-msg-format, old type nil
analyzer: updating variable log4e--current-msg-buffer, old type nil
analyzer: updating variable alert-styles, old type nil
analyzer: updating variable alert-internal-configuration, old type nil
analyzer: updating variable alert-notifications-ids, old type nil
analyzer: updating variable alert-active-alerts, old type nil
Other must be ‘elsa-type-child-p’
Fuco1 commented 5 years ago

@TatriX Yes, I think I've accidentally included another error in the master :( (see also #146).

I will try to fix it today. Checking out 6aabd45 should work, it does have the compilation fix but does not have the one I introduced after that.

Thanks for the testing by the way, much appreciated!

TatriX commented 5 years ago

That commit works, thanks!

anquegi commented 5 years ago

Using the emacs web server package, and after requiring it

(require 'web-server)
(require 'simple-server-web)
(require 'simple-server-api)

(defvar simple-server--port 9000
  "start instante on port")

(defvar simple-server--handlers ()
  "List to add simple server handlers")

(provide 'simple-server)
;;; simple-server.el ends here

I get this problem:

Suspicious state from syntax checker emacs-lisp-elsa: Flycheck checker emacs-lisp-elsa returned non-zero exit code 255, but its output contained no errors: analyzer: updating variable ws-status-codes, old type nil
analyzer: updating variable ws-servers, old type nil
analyzer: updating variable ws-log-time-format, old type nil
analyzer: updating variable ws-guid, old type nil
No applicable method: clone, nil

Try installing a more recent version of emacs-lisp-elsa, and please open a bug report if the issue persists in the latest release.  Thanks!
Fuco1 commented 5 years ago

@anquegi this seems to be a different issue, there is some type which has no clone method defined. Can you put it in a separate issue please? :heart:

Fuco1 commented 5 years ago

The defgroup from OP now works on the latest version which was probably fixed by the changes introduced in #111

cpitclaudel commented 5 years ago

Thanks!