emacs-elsa / Elsa

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

Error on `(require 'elsa)`: `(void-variable elsa-type)` #216

Closed alphapapa closed 1 year ago

alphapapa commented 1 year ago

Possibly related to https://github.com/emacs-elsa/Elsa/issues/175:

When I install the latest version of Elsa from MELPA into a clean Emacs 28.1 configuration and (require 'elsa) I get this backtrace:

Debugger entered--Lisp error: (void-variable elsa-type)
  byte-code("\301\10\302\211\303\304%\210\305\306\307\306\310\302#\311#\210\305\312\307\312\313\302#\314#\210\305\315\307\315\316\302#\317#\210\305\320\307\320\321\302#\322#\210\305\323..." [elsa-type defclass nil :abstract t defalias elsa-type-sum cl-generic-define (this other) "Return the sum of THIS and OTHER type.\n\nA sum acce..." elsa-type-diff (this other) "Return the difference of THIS without OTHER.\n\nThe ..." elsa-type-intersect (this other) "Return the intersection of THIS and OTHER.\n\nThe in..." elsa-type-normalize (type) "Normalize TYPE to its most simplest form.\n\n(fn TYP..." elsa-type-describe (type) "Return a string representation of TYPE.\n\n(fn TYPE)" cl-generic-define-method #f(compiled-function (type) #<bytecode 0x20772fd9e7d888f>) elsa-type-make-non-nullable (type) "Make TYPE non-nullable.\n\nThis is the same as diffi..." provide] 6)
  require(elsa-type)
  byte-code("\301\302!\210\303\20\301\304!\210\301\305!\210\301\306!\210\301\307!\210\301\310!\210\301\311!\210\301\312!\210\301\313!\210\314\315\316\317!\"\210\314\320\321\317!..." [eieio-backward-compatibility require eieio nil cl-macs trinary dash elsa-type elsa-types-simple elsa-methods elsa-explainer elsa-structure-slot defalias elsa-type--structured-p eieio-make-class-predicate elsa-type--structured elsa-type--structured--eieio-childp eieio-make-child-predicate define-symbol-prop cl-deftype-satisfies eieio-defclass-internal ((slots :type hash-table :initarg :slots :initform (make-hash-table)) (extends :type (list-of symbol) :initarg :extends :initform nil)) (:documentation "Structured Elsa type with named slots.\n\nThis class...")] 6)
  require(elsa-types)
  byte-code("\301\302!\210\303\20\301\304!\210\301\305!\210\301\306!\210\301\307!\210\301\310!\210\301\311!\210\301\312!\210\301\313!\210\301\314!\210\301\315!\210\301\316!\210..." [eieio-backward-compatibility require eieio nil cl-lib cl-extra warnings jka-compr dash ansi async elsa-dependencies elsa-types elsa-scope elsa-state elsa-error elsa-analyser elsa-reader elsa-log elsa-declare elsa-ruleset elsa-extension-builtin elsa-typed-syntax elsa-typed-thingatpt elsa-typed-subr] 2)
  require(elsa)
  (progn (require 'elsa))
  elisp--eval-last-sexp(nil)
  eval-last-sexp(nil)
  funcall-interactively(eval-last-sexp nil)
  command-execute(eval-last-sexp)
alphapapa commented 1 year ago

Looks like using eval-and-compile instead of eval-when-compile in elsa-type-algebra.el helps:

(eval-and-compile
  (defvar elsa-type-debug nil))
alphapapa commented 1 year ago

Also, elsa-log.el needs (require 'dash). (I'm finding these problems by linting compilation with makem.sh, BTW. ;)

alphapapa commented 1 year ago

And elsa-type.el needs to (require 'eieio).

alphapapa commented 1 year ago

And elsa-explainer.el needs (defvar elsa-explainer-message nil).

alphapapa commented 1 year ago

With those changes, and calling elsa-run instead of elsa-run-files-and-exit, and adding the -with-exit option (which should probably be --with-exit, BTW, although why is this option even needed?), it seems to work when called from makem.sh now.

alphapapa commented 1 year ago

And while I'm here, before I file another issue: are cl-defun argument lists not supported? e.g. with this code:

(cl-defun ement-room-list (&key (buffer-name "*Ement Room List*")
                                (keys ement-room-list-default-keys)
                                (display-buffer-action '((display-buffer-reuse-window display-buffer-same-window)))
                                ;; visibility-fn
                                )
...)

Elsa says that buffer-name is a free variable in the body of the function.

And it's thinking that keywords in cl-loop forms are free variables, too. Am I doing something wrong?

Fuco1 commented 1 year ago

Macros don't work very well because they are super hard to do safely, see #205 Elsa never runs any code including macros so macro expansions are basically unknown. Some macros are supported by special-casing the evaluation rules, but a general solution does not yet exist.

cl-defun is not supported yet.

About the byte compilation, I'm really not that careful about it and should be because installed packages byte compile :blush: Obviously I always run it interpreted as I develop :/ I'll add the missing requires, thanks for that. How did you find the errors, when I compile for example elsa-type.el from dired I get no warnings.

With those changes, and calling elsa-run instead of elsa-run-files-and-exit, and adding the -with-exit option (which should probably be --with-exit, BTW, although why is this option even needed?), it seems to work when called from makem.sh now.

This is the old docstring. I should add it back somewhere

-  "Analyze files, output errors to stdout and set error code.
-
-This function does the same as `elsa-run' except it also sets the
-exit code to non-zero in case there were any errors during
-analysis.
-
-It exists because flycheck complains when process exits with
-non-zero status."

-with-exit because Emacs uses single dash options like that /shrug

Fuco1 commented 1 year ago

And elsa-explainer.el needs (defvar elsa-explainer-message nil).

This is some legacy eieio stuff. Every time eieio is required there must be (eval-and-compile (setq eieio-backward-compatibility nil)) after it to turn off the legacy stuff.

It's super annoying and I've discussed it with Stefan Monnier briefly. There was some discussion on emacs devel of doing something about it

alphapapa commented 1 year ago

Macros don't work very well because they are super hard to do safely, see #205 Elsa never runs any code including macros so macro expansions are basically unknown. Some macros are supported by special-casing the evaluation rules, but a general solution does not yet exist.

Ah, I see. That sounds like a serious challenge. Can they be annotated for Elsa, anyway? I use pcase and pcase-let liberally, which seems to be giving me thousands of such errors on Ement.

cl-defun is not supported yet.

:( I use it so much...

About the byte compilation, I'm really not that careful about it and should be because installed packages byte compile blush Obviously I always run it interpreted as I develop :/ I'll add the missing requires, thanks for that. How did you find the errors, when I compile for example elsa-type.el from dired I get no warnings.

I found them because makem.sh compiles each file in a separate Emacs process by default (which is necessary because when installing a package, the order in which the files are compiled isn't guaranteed, so the only way to be safe is for each file to compile independently without error--I get many fewer bug reports on my packages since I started doing this).

With those changes, and calling elsa-run instead of elsa-run-files-and-exit, and adding the -with-exit option (which should probably be --with-exit, BTW, although why is this option even needed?), it seems to work when called from makem.sh now.

This is the old docstring. I should add it back somewhere

Thanks.

-with-exit because Emacs uses single dash options like that /shrug

Ah, well, it does support some of those, but also the double-prefixed ones. I guess the single-prefixed ones are "legacy," since AFAIK the official GNU style is to use double-prefixes for long options. No big deal, though.

Thanks for your work.

Fuco1 commented 1 year ago

AFAIK the official GNU style is to use double-prefixes for long options. No big deal, though.

If that's so I'll change it to double dash, I like that a lot more as well.

Fuco1 commented 1 year ago

I'm going to close this issue. There is a separate one for cl-defun support and also for the CLI options.