Using `racket/private/kw-syntax-local` as the source for
`local-expand`, etc., means that modules that re-export that
one (such as `scheme/base`) get the right documentation links.
When an embedding application calls `scheme_basic_env` a
second time, it's supposed to reset the main namespace, but
the new expander wasn't reset correctly.
* Fix handling of single-percision infinities and nan
* Document that non-`hash-eq?` hash tables are accepted by `jsexpr?`.
* Document that the value of `json-null` is recognized using `eq?`
* Use `case` instead of `assoc`.
* Use contracts
Delay reporting of potential problems until an actual problem
is detected. Correct a mismatch between original and renamed
symbols to restore detection of problems.
* When you delete a file in Windows, then the name doesn't go away
until the file is closed in all processes (and background tasks like
search indexing may open files behind your back). Worse, attempting
to create a new file with the same name reports a permission error,
not a file-exists error; there's seems to be no way to tell whether
a permission error was really a file-exists error.
This creates trouble for `make-temporary-file` when files are
created, deleted, and created again quickly enough and when
something like a search indexer runs in the background (which is the
usual Windows configuration). In practice, that kind of collision
happens often for `raco setup` on my machine.
To compensate, make `make-temporary-file` try up to 32 times on a
permission error. A collision that many times seems extremely
unlikely, and it seems ok to delay an actual permission error.
Windows provides a GetTempFileName function from "kernel.dll" that
must be able to deal with this somehow --- perhaps because it's in
the kernel --- but it doesn't solve the problem for making temporary
directories, hence the 32-tries approach for now.
* When a deleted file's name persists because the file is open in some
process, then a directory containing the file cannot be deleted.
This creates trouble for `delete-directory/files`, since
`delete-file` on a directory's content doesn't necessarily make the
directory empty. In practice, this happens often for package
upgrades on my machine, where the package system wants to delete a
short-lived working space that the indexer is trying to scan.
To compenstate, change `delete-directory/files` to delete a file by
first moving it to the temporary directory with a fresh name, and
then delete the file there. It may take a while for a file to
disappear from the temporary directory, but meanwhile it's not in
the way of the original enclosing directory.
* When a file is open by any process, it prevents renaming any
ancestor directory of the file.
This creates trouble for the package system, which installs a
package by unpacking it in a temporary place and then moving it by
renaming. The package system also removes a package by renaming it
to a subdirectory of a ".trash" directory. If a background indexer
has a package file open, the move fails. In practice, a move fails
often on my machine when I'm attempting to upgrade many packages.
To compensate, make the package system fall back to copy + delete
if moving fails with a permission error.
Bind variables in a way that allows `local-expand` (with an empty stop
list) to replace a reference to the binding with one that has the same
scopes as the binding.
This repair was motivated by tests in the "rex" package. The
new test added here failed before by finding 'new both times,
but in the "rex" case, the mixup led to the same variable
being imported and exported at the linklet level.
struct-out was putting the super-struct's accessors into two parts of a
struct-info: the accessor list and the mutator list
this commit puts the accessors only in the accessor list and the
mutators in the mutator list
Using a frame pointer for the ABI of internal helper functions
should make the stack friendlier to tools like `perf`. There
may be a small performance cost, though.
giving plain s-exps like you would for `require` is unlikely to work as expected.
Need use something that evaluates to the appropriate s-exp you want.
Added more examples of different `dynamic-require` uses.
Alexis's repair, and as she notes, forcing a `post-expansion` context
value in the core `#%module-begin` expander may allow a simplification
in "definition-context.rkt". But it's not immediately obvious, so save
that potential improvement for later.
Relevant to #2118
When `local-expand` receives one or more internal definition contexts,
it would forget about any current post-expansion scopes. That's
particularly a problem in a 'module-begin expansion context, where the
post-expansion scope ensures that any bindings are suitably
phase-specific.
Closes#2115
This is similar to the recent change of functions with optional
values. Using unsafe-undefined instead of a gensym makes it easier
to avoid the check of the missing argument.
When the separator is a string, these function construct a regexp
that is cached to make repeated calls faster. But when the string
is mutated it is necessary to recalculate the regexp.
Commit 32b256886e adds shifts in one place where it shoouldn't;
the "determinsitic-zo" test exposed the problem.
Also, avoid adding shifts that will have no effect, which avoids
accumulating useless shifts in some top-level contexts.
Various parts of the expander, including `local-expand`, always
flipped the use-site scope when flipping an introduction scope. Onlt
`syntax-local-introduce` should flip both of them, though.
Closes#2112
When expanding in a namespace for a module unmarshaled from ".zo"
form, a scope corresponding to the module's "inside edge" is added to
every expansion. Before this repair, the scope was detached from
module path index shifts that might apply to the bindings (including
references to bulk bindings). Repair the problem by adding suitable
shifts when adding the scope.
Thanks to William Hatch for the bug report.