[plt-scheme] Chasing down chaining compile-time issue with contracts and structures

From: Daniel Yoo (dyoo at cs.wpi.edu)
Date: Fri Apr 27 15:07:26 EDT 2007

Hi everyone,

The following set of modules (modules a, b, and c) raises a contract-level 
error at compile time.  (I'm at r6058 from svn):

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(module a mzscheme
   (require (lib "contract.ss"))
   (define-struct a (x))
   (provide/contract [struct a ([x number?])]))

(module b mzscheme
   (require "a.ss"
            (lib "contract.ss"))
   (define-struct (b a) (y))
   (provide/contract [struct (b a) ([x number?] [y number?])]))

(module c mzscheme
   (require "b.ss"
            (lib "contract.ss"))
   (define-struct (c b) (z))
   (provide/contract [struct (c b) ([x number?] [y number?] [z number?])]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


The error I see is:

####################################################################
string-length: expects argument of type <string>; given #f
  === context ===
/home/dyoo/local/plt-svn/collects/mzlib/private/contract.ss:373:15: loop
/home/dyoo/local/plt-svn/collects/mzlib/private/contract.ss:270:9: 
build-struct-code
try-next
/home/dyoo/local/plt-svn/collects/mzlib/private/contract.ss:166:2
/home/dyoo/local/plt-svn/collects/mzlib/cm.ss:112:2: compile-zo
####################################################################

The line numbers will be slightly off, since I've augmented my source tree 
with some debugging printf statements, but the bug is around the place 
where the contract compiler is checking field names of structure contracts 
to make sure those field names are valid.


I've been able to isolate the cause of the problem to a weirdness in 
constructor->struct-name in collects/private/contract.ss: it sometimes 
returns a false value when it must return a symbol.  But I don't know yet 
how to fix this properly yet.  The given constructor names being passed 
through are weird; I'm seeing values like:

     * make-c
     * provide/contract-id-make-b
     * provide/contract-id-make-a

being passed into that function when module C is being compiled.  I'm not 
confident enough of my understanding of contract.ss just to change the 
regular expression there in constructor->struct-name.  The parent 
structure constructor names that are being passed look wrong to me... but 
again, I don't yet understand the inner workings of the contract system 
well enough to make the correct fix.


Just as a side note: I've been tracking this down because I can't get Dave 
Herman's javascript.plt to work for me, and the underlying cause seems to 
be this contract-level bug.


Posted on the users mailing list.