repair prop:impersonator-of interaction with {impersonator,chaperone}-of?

Relevant to #2644
This commit is contained in:
Matthew Flatt 2019-05-15 10:32:06 -06:00
parent 6ae082fccd
commit b3f66a4973
4 changed files with 27 additions and 8 deletions

View File

@ -129,15 +129,19 @@ proceeds by comparing @racket[_v1] and @racket[_v2] recursively (as with
Indicates whether @racket[v1] can be considered equivalent modulo
chaperones to @racket[v2].
For values that include no chaperones, @racket[v1] and @racket[v2] can
be considered chaperones of each other if they are @racket[equal?],
except that mutable vectors, boxes, strings, byte strings, and mutable
structures within @racket[v1] and @racket[v2] must be @racket[eq?].
For values that include no chaperones or other impersonators,
@racket[v1] and @racket[v2] can be considered chaperones of each other
if they are @racket[equal?], except that corresponding mutable
vectors, boxes, strings, byte strings, and mutable structures within
@racket[v1] and @racket[v2] must be @racket[eq?].
Otherwise, chaperones within @racket[v2] must be intact within
@racket[v1] analogous to way that @racket[impersonator-of?] requires
that impersonators are preserved, except that @racket[prop:impersonator-of]
has no analog for @racket[chaperone-of?].}
Otherwise, chaperones and other impersonators within @racket[v2] must
be intact within @racket[v1] analogous to way that
@racket[impersonator-of?] requires that impersonators are preserved.
Furthermore, @racket[v1] must not have any non-chaperone impersonators
whose corresponding value in @racket[v2] is not the same impersonator.
Note that @racket[chaperone-of?] implies @racket[impersonator-of?],
but not vice-versa.}
@defproc[(impersonator-ephemeron [v any/c]) ephemeron?]{

View File

@ -2680,6 +2680,8 @@
(test #t impersonator-of? (make-a #f 2) a1)
(test #t chaperone-of? (make-a #f 2) a1)
(test #t impersonator-of? (make-a a1 3) a1)
(test #f impersonator-of? a1 (make-a a1 2))
(test #f chaperone-of? a1 (make-a a1 2))
(test #t impersonator-of? (make-a-more a1 3 8) a1)
(test #f chaperone-of? (make-a a1 3) a1)
(test #t equal? (make-a a1 3) a1)

View File

@ -101,6 +101,11 @@
(or (check-union-find ctx a b)
(let ([ctx (deeper-context ctx)])
(equal? (or a2 a) (or b2 b) ctx)))]
[(and (not (eq? mode 'equal?))
(extract-impersonator-of mode b))
;; Second argument is an impersonator, so
;; `impersonator-of?` or `chaperone-of?` fails
#f]
[else
;; No `prop:impersonator-of`, so check for
;; `prop:equal+hash` or transparency

View File

@ -726,6 +726,14 @@ int is_equal (Scheme_Object *obj1, Scheme_Object *obj2, Equal_Info *eql)
if (procs2) { obj2 = procs2; orig_obj2 = obj2; }
goto top_after_next;
} else {
/* don't discard `prop:impersonator-of` if checking for `impersonator-of?`
or `chaperone-of?` */
if (eql->for_chaperone) {
procs2 = scheme_struct_type_property_ref(scheme_impersonator_of_property, (Scheme_Object *)st2);
if (procs2 && scheme_apply_impersonator_of(eql->for_chaperone, procs2, obj2))
return 0;
}
procs1 = scheme_struct_type_property_ref(scheme_equal_property, (Scheme_Object *)st1);
if (procs1 && (st1 != st2)) {
procs2 = scheme_struct_type_property_ref(scheme_equal_property, (Scheme_Object *)st2);