The `declare_program!` and `declare_loader!` macros both expand to
new macro definitions (based on the `$name` argument). These 'inner'
macros make use of the special `$crate` metavariable to access items in
the crate where the 'inner' macros is defined.
However, this only works due to a bug in rustc. When a macro is
expanded, all `$crate` tokens in its output are 'marked' as being
resolved in the defining crate of that macro. An inner macro (including
the body of its arms) is 'just' another set of tokens that appears in
the body of the outer macro, so any `$crate` identifiers used there are
resolved relative to the 'outer' macro.
For example, consider the following code:
```rust
macro_rules! outer {
() => {
macro_rules! inner {
() => {
$crate::Foo
}
}
}
}
```
The path `$crate::Foo` will be resolved relative to the crate that defines `outer`,
**not** the crate which defines `inner`.
However, rustc currently loses this extra resolution information
(referred to as 'hygiene' information) when a crate is serialized.
In the above example, this means that the macro `inner` (which gets
defined in whatever crate invokes `outer!`) will behave differently
depending on which crate it is invoked from:
When `inner` is invoked from the same crate in which it is defined,
the hygiene information will still be available,
which will cause `$crate::Foo` to be resolved in the crate which defines 'outer'.
When `inner` is invoked from a different crate, it will be loaded from
the metadata of the crate which defines 'inner'. Since the hygiene
information is currently lost, rust will 'forget' that `$crate::Foo` is
supposed to be resolved in the context of 'outer'. Instead, it will be
resolved relative to the crate which defines 'inner', which can cause
incorrect code to compile.
This bug will soon be fixed in rust (see https://github.com/rust-lang/rust/pull/72121),
which will break `declare_program!` and `declare_loader!`. Fortunately,
it's possible to obtain the desired behavior (`$crate` resolving in the
context of the 'inner' macro) by use of a procedural macro.
This commit adds a `respan!` proc-macro to the `sdk/macro` crate.
Using the newly-stabilized (on Nightly) `Span::resolved_at` method,
the `$crate` identifier can be made to be resolved in the context of the
proper crate.
Since `Span::resolved_at` is only stable on the latest nightly,
referencing it on an earlier version of Rust will cause a compilation error.
This requires the `rustversion` crate to be used, which allows conditionally
compiling code epending on the Rust compiler version in use. Since this method is already
stabilized in the latest nightly, there will never be a situation where
the hygiene bug is fixed (e.g. https://github.com/rust-lang/rust/pull/72121)
is merged but we are unable to call `Span::resolved_at`.
* Move bank (de)serialisation logic from bank and snapshot_utils to serde_snapshot.
Add sanity assertions between genesis config and bank fields on deserialisation.
Atomically update atomic bool in quote_for_specialization_detection().
Use same genesis config when restoring snapshots in test cases.
* Tidy up namings and duplicate structs to version
* Apply struct renames to tests
* Update abi hashes
Co-authored-by: Ryo Onodera <ryoqun@gmail.com>
* fix: ignore unknown fields in more RPC responses
* Remove mdbook infrastructure
* Delete gitattributes and other theme related items
Move all docs to /docs folder to support Docusaurus
* all docs need to be moved to /docs
* can be changed in the future
Add Docusaurus infrastructure
* initialize docusaurus repo
Remove trailing whitespace, add support for eslint
Change Docusaurus configuration to support `src`
* No need to rename the folder! Change a setting and we're all good to
go.
* Fixing rebase items
* Remove unneccessary markdown file, fix type
* Some fonts are hard to read. Others, not so much. Rubik, you've been
sidelined. Roboto, into the limelight!
* As much as we all love tutorials, I think we all can navigate around a
markdown file. Say goodbye, `mdx.md`.
* Setup deployment infrastructure
* Move docs job from buildkite to travic
* Fix travis config
* Add vercel token to travis config
* Only deploy docs after merge
* Docker rust env
* Revert "Docker rust env"
This reverts commit f84bc208e807aab1c0d97c7588bbfada1fedfa7c.
* Build CLI usage from docker
* Pacify shellcheck
* Run job on PR and new commits for publication
* Update README
* Fix svg image building
* shellcheck
Co-authored-by: Michael Vines <mvines@gmail.com>
Co-authored-by: Ryan Shea <rmshea@users.noreply.github.com>
Co-authored-by: publish-docs.sh <maintainers@solana.com>