The behaviors below can be seen on 29, 30, 31 (I don't have an earlier Emacs to test but these issues probably are long-standing). Let's discuss these as I suspect there may be historical reasons for these behaviors that I'm unaware of, or maybe these are legitimate, even if old. It's also possible that I'm misunderstanding something.
Issue 1:
(file-name-directory "~") ; returns nil but I think this should return "~/":
(file-name-directory
(abbreviate-file-name "/home/username")) ; same
(file-name-directory
(abbreviate-file-name "/Users/username")) ; for all us macOS users
Issue 2:
I think file-equal-p should accept nil and consider it unspecified as in its docstring: "If FILE1 or FILE2 does not exist, the return value is unspecified."
And/or find-file-name-handler should accept nil and then return nil.
(file-equal-p "~" "~") ; t
(file-equal-p "~" "/home/username") ; t
(file-equal-p "~" (file-name-directory "~")) ; boom
;; (wrong-type-argument stringp nil)
;; find-file-name-handler(nil file-equal-p)
Issue 3:
project-forget-projects-under crashes when `project-list-file' contains "/home/username", which appears in my remembered project list.
(defun project--read-project-list ()
...
(abbreviate-file-name name) ; converts "/home/username" to "~"
(defun project-forget-projects-under ()
...
(dolist (proj (project-known-project-roots))
(when (file-equal-p (file-name-directory proj) dir) ; <--- boom on nil
I'm happy to submit patches for any or all of these including guarding project-forget-projects-under to check for nil and/or amending project--read-project-list to convert "~" to "~/" as workarounds, with each submitted against a discrete bug number.
-Stephane