SUBTYPEP incorrectly returns NIL, NIL in the presence of non-existent types

Bug #716819 reported by Jean-Philippe Paradis
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Won't Fix
Low
Unassigned

Bug Description

What I do:
(subtypep 'fake-type 'other-fake-type)

What happens:
NIL, NIL is returned.

What I expected to happen:
First of all, I'm not sure what the consequences of using such non-existent types are supposed to be. The definition of subtypep doesn't seem to tell. (I note that SUBTYPEP has "Exceptional situations: None", which I didn't expect.) However, the standard says that (typep t 'fake-type) has undefined behavior, but SBCL already throws an error for that (proving its ability to detect such invalid types)... So subtypep should be able to throw an error too. (There might be implementation or performance concerns why this isn't done?)

More importantly, the definition for SUBTYPEP says: "subtypep is permitted to return the values false and false only when at least one argument involves one of these type specifiers: and, eql, the list form of function, member, not, or, satisfies, or values. [...] One consequence of this is that if neither type-1 nor type-2 involves any of these type specifiers, then subtypep is obliged to determine the relationship accurately."

In light of this, it seems clear that the exhibited behavior is in violation of the standard.

SBCL version: 1.0.42
uname -a: Linux dynamorph 2.6.32-27-generic #49-Ubuntu SMP Wed Dec 1 23:52:12 UTC 2010 i686 GNU/Linux

*features*:
(:SWANK :QUICKLISP :SB-BSD-SOCKETS-ADDRINFO :ASDF2 :ASDF :ANSI-CL :COMMON-LISP
 :SBCL :SB-DOC :SB-TEST :SB-LDB :SB-PACKAGE-LOCKS :SB-UNICODE :SB-EVAL
 :SB-SOURCE-LOCATIONS :IEEE-FLOATING-POINT :X86 :UNIX :ELF :LINUX :SB-THREAD
 :LARGEFILE :GENCGC :STACK-GROWS-DOWNWARD-NOT-UPWARD :C-STACK-IS-CONTROL-STACK
 :COMPARE-AND-SWAP-VOPS :UNWIND-TO-FRAME-AND-CALL-VOP :RAW-INSTANCE-INIT-VOPS
 :STACK-ALLOCATABLE-CLOSURES :STACK-ALLOCATABLE-VECTORS
 :STACK-ALLOCATABLE-LISTS :STACK-ALLOCATABLE-FIXED-OBJECTS :ALIEN-CALLBACKS
 :CYCLE-COUNTER :INLINE-CONSTANTS :MEMORY-BARRIER-VOPS :LINKAGE-TABLE
 :OS-PROVIDES-DLOPEN :OS-PROVIDES-PUTWC :OS-PROVIDES-SUSECONDS-T)

Revision history for this message
Nikodemus Siivola (nikodemus) wrote :

Not sure, but needs proper consideration for sure.

SBCL considers unknown-at-the-moment types pretty much as if they were SATISFIES types involving an unknown function.

This may be a divergence, and if so it needs to be either fixed or documented (and a rationale given.) If it turns out the be allowed, it should still be documented because I don't think you're the first person to wonder about this...

Changed in sbcl:
importance: Undecided → Low
status: New → Confirmed
Revision history for this message
Samuel Edwin Ward (seward-u) wrote :

Very interesting!

Obviously, we can't return <anything>, t because we don't know what the types are, but I'm not sure if we can signal a condition as there are no defined exceptional situations.

Revision history for this message
Nikodemus Siivola (nikodemus) wrote :

Well, divergences from ANSI are actually allowed as long as they are documented, and I can see people /wanting/ an error -- or at least a full warning -- for unknown types in subtypep.

One possibility is to have an sb-ext:*on-unknown-subtypep* variable, with possible values nil, :warn, and :error, defaulting to NIL.

Another would be an *unknown-type-hook*.

Yet another would be to signal (without forcing entry to debugger) an UNKNOWN-TYPE-SPECIFIER condition when such a specifier is parsed, so you could do

  (handler-bind ((unknown-type-specifier (lambda (c) (error c)))) (compile-file "stuff"))

to catch them.

Actually, I think I like this last one the best.

Revision history for this message
Douglas Katzman (dougk) wrote :

As to being nonconforming or a divergence from the spec, it is always permissible to return NIL and NIL, barring the situations in which it isn't permissible.

Clozure:
Welcome to Clozure Common Lisp Version 1.10-r16196 (LinuxX8664)!
...
? (subtypep 'foo 'bar)
NIL
NIL

ECL:
ECL (Embeddable Common-Lisp) 16.1.3 (git:UNKNOWN)
...
> (subtypep 'foo 'bar)
NIL
NIL

ABCL:
Armed Bear Common Lisp 1.5.0
Java 1.8.0_181-google-v7 Google Inc.
...
CL-USER(1): (subtypep 'foo 'bar)
NIL
T

(ABCL is potentially "actually wrong" because it claims to be _certain_ that the answer is NIL)

So given that we do signal a condition, I'm somewhat inclined to say this issue is "fixed".

Revision history for this message
Jean-Philippe Paradis (hexstream) wrote :

"As to being nonconforming or a divergence from the spec, it is always permissible to return NIL and NIL, barring the situations in which it isn't permissible."

I believe the passage of the spec that I already quoted directly contradicts your assertion. Here it is again:

"subtypep is permitted to return the values false and false only when at least one argument involves one of these type specifiers: and, eql, the list form of function, member, not, or, satisfies, or values. [...] One consequence of this is that if neither type-1 nor type-2 involves any of these type specifiers, then subtypep is obliged to determine the relationship accurately."

It seems that multiple implementations are non-conforming in this case.
I don't believe that this issue is fixed at all.

Revision history for this message
Stas Boukarev (stassats) wrote :

>One consequence of this is that if neither type-1 nor type-2 involves any of
these type specifiers
Which cannot be determined if the type is not defined. It's unclear what benefit would it provide to signal an error other than to be annoying.

Changed in sbcl:
status: Confirmed → Won't Fix
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.