This strategy has been successful for the package-build service,
and it will hopefully cut down on spurious snapshot build failures
that happen when a VM's networking doesn't start up quickly enough.
If the target folder exists, let the user know and give up. (This
seems safer than trying to delete the folder, since there might be
other files in the folder than the original files, and the installer
doesn't currently keep a list of installed files.)
A public method definition and a private field that contains
a function are hard to distinguish without traversing the entire
class body, which caused TR to fail to detect the private field
case. TR now uses more compile-time state to precisely
distinguish the cases.
Also fixes a related bug in which TR would incorrectly handle
multiple private fields defined with a single `define-values`.
Closes PR 14788
The check that the current meta-continuation matches the captured one
would always fail (I think), since the current meta-continuation is
pruned on capture. Keep a weak link to the original meta-continuation
to enable detection of capturing a continuation that matches or
extends one that was previously captured.
Enabling sharing exposed a problem with the code that saves
continuation marks for partial sharing, since that implementation
became out of sync with the main implementation (so merge the
implementations).
avoids piling up redundant instanceof/c contracts
This is not a general purpose solution, but instead a hack that covers
certain hopefully likely patterns of redundant contracts for objects.
This commit looks for redundant contracts according in a slightly more
general pattern than just "is the most recently attached contract
stronger than the one I'm about to put on here and does it have the
same blame labels?", because that predicate isn't good enough to cover
the example below. In the example below, we repeatedly get the same
contract put on an object, but with different blame labels. So we need
to drop "inner" contracts. That is, when we have two contracts on
there and we go to add the third, we can tell that the second one
would no longer ever signal blame, so we can keep just the first in
the third.
More concretely, if we had these two contracts on 'v' with the given
blame labels (higher lines means the contract is "outside" or applied
later and the blame labels are in positive/negative order):
(-> x y) <c,d>
(-> x y) <a,b>
then the two possible blames we get here are blaming d for a non-x
argument and blaming a for a non-y result. And now lets say we add a
third contract to the stack that's a copy of the first, but possibly
with different blame labels:
(-> x y) <e,f>
(-> x y) <c,d>
(-> x y) <a,b>
Now we can blame f for non-x argument and a for a non-y result, both
of which are things covered by the first and third contract, so we can
safely drop the middle one and use this stack:
(-> x y) <e,f>
(-> x y) <a,b>
The example above is couched in terms of arrow contracts, but this
commit doesn't do this for arrow contracts, it does it for
instanceof/c contracts.
And also the way that we tell that the inner contract is redundant
isn't that it is equal; instead we use contract-stronger?. In
particular, the above reasoning works, I believe, when we have that
the inner contract is stronger than the one we're removing and when
the outer contract is also stronger than the one we're
removing. That's the check that actually happens in the code.
-------
The code below is the example below is an example Asumu sent me (but
with the TR parts stripped out). Before this commit, the contract
wrapping grows without bound, but with this commit it stays constant.
In the example below we get only two different sets of blame labels
(and equal contracts) and thus are actually more contracts that could
be eliminated, but this commit does limit it to just two contracts. (I
think it could be alternating between one and two contracts instead of
always two if the code that dropped the contracts were more clever.)
#lang racket/base
(module State racket/base
(require racket/contract racket/class)
(define state/c
(recursive-contract
(class/c
[m (-> any/c (instanceof/c state/c))]
[n (-> any/c (instanceof/c state/c))])))
(define state%
(class object%
(super-new)
(define/public (m) (send this n))
(define/public (n) (new state%))))
(define (tree-next o) (send o m))
(define (make-tree) (new state%))
make-tree
(provide
(contract-out
[tree-next (-> (instanceof/c state/c) (instanceof/c state/c))]
[make-tree (-> (instanceof/c state/c))])))
(require (submod "." State))
(require racket/sandbox)
(with-limits #f
100
(let loop ([o1 (make-tree)] [n 0])
(printf "~a\n" n)
(define o2 (tree-next o1))
(loop o2 (add1 n))))
Contrary to the comment for 0b71b8481d, the `unstable/options`
implementation used the first argument to a mutator wrapper.
Adjust to close over the wrapped value.
The `typeset-code` function assumed that a lexeme must be `eof` on an
end-of-file, but `test:color<%>` allows it to be anything. Instead,
the check should be on type as 'eof.
When calling a wrapper procedure for a field accessor or mutator,
provide the structure that was originally passed to the accessor or
mutator, instead of the value that was wrapped to create an
impersonator.
This is a backward-incompatible change, but I can't find any uses of
that initial argument to the wrapper procedure. Also, a wrapper can
capture the original value in its closure, while passing "self" allows
wrappers that are sensitive to overridden impersonator properties.
This handles contract generation for recursive or
mutually recursive Name types in the static contract
framework.
Instead of just generating recursive-sc static contracts,
it memoizes the recursive contract within a single
type->contract call by indirecting through a table.
When static contracts are instantiated, the table is
consulted for computing contract kind information and for
generating the actual contracts for the recursive names.
The OS doesn't necessarily react to a zero-sized buffer the way
that `udp-receive!` is supposed to work, so provide only a
non-zero-sized buffer to the OS.
Random tests that are implciitly injected into a program should
declare themselves as such when they fail. Otherwise, random
crashes are really confusing.