tov / dssl2

A data structures student language, version 2
MIT License
9 stars 4 forks source link

Different behavior when compiled with `raco make` #14

Open tov opened 4 years ago

tov commented 4 years ago

Compiling with raco make makes it impossible to implement an interface in a different source file than where the interface is defined. In particular, objects of a class C that implements an interface I imported from another source file are not actually considered to implement interface I by the I? and I! contracts.

How to reproduce

  1. Create a file lib.rkt containing:

    #lang dssl2
    
    interface I: pass
  2. Create a file client.rkt containing:

    #lang dssl2
    
    import 'lib.rkt'
    
    class C (I):
        def __init__(self): pass
    
    # This should succeed because C implements I, but it fails if you run
    # `raco make` first. (It also fails in DrRacket.)
    let o: I! = C()
  3. Run client.rkt:

    $ racket client.rkt
    $
  4. Compile client.rkt and run it again:

    $ raco make client.rkt
    $ racket client.rkt
    o: broke its own contract;
     class C does not implement interface I
      in: I!
      contract from: (definition o)
      blaming: (definition o)
       (assuming the contract is correct)
      at: /Users/tov/Desktop/raco-make-weirdness/client.rkt:10.4
      context...:
       /Applications/Racket v7.4/collects/racket/contract/private/blame.rkt:347:0: raise-blame-error16
       "/Users/tov/Desktop/raco-make-weirdness/client.rkt": [running body]
       temp37_0
       for-loop
       run-module-instance!125
       perform-require!78
    $
  5. Delete the compilation artifacts and run it again:

    $ rm -R compiled
    $ racket client.rkt
    $