diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2f2b9b29..5be0bd51 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -4,7 +4,7 @@ on: merge_group: env: - MDBOOK_VERSION: 0.4.52 + MDBOOK_VERSION: 0.5.1 jobs: code-tests: diff --git a/docs/review-policy.md b/docs/review-policy.md index 9d61151d..2195c444 100644 --- a/docs/review-policy.md +++ b/docs/review-policy.md @@ -1,5 +1,13 @@ Team members are given permission to merge changes from other contributors in the repository. There are different guidelines for reviewing based on the kind of changes being made: +## Review principles + +Reviewers and authors should focus on a few key principles during the review process: + +* **Understandability**: Language within the Reference should be understandable to most members of the Project. Contributions should assumes that readers are familiar with the rest of the content of the Reference, but, wherever possible, sections should facilitate that understanding by linking to related content. +* **Defensibility**: When the lang-docs team merges a change to the Reference, they are agreeing to take responsibility for it going forward. Team members need to feel confident defending and explaining the correctness of content within the Reference. Whenever possible, changes to the Reference should back up any claims with concise examples to verify correctness. +* **Voice**: Authors are not expected to have competence as a specification writer when drafting new contributions to the Reference. So long as claims are understandable and defensible, it is fine for PRs to be written in a casual tone or with the voice of the author instead of the voice of the Reference. Team members will bring editorial experience as part of their reviews and will revise the phrasing, organization, style, etc. to fit the Reference before merging if necessary. + ## Policy changes - Significant changes to the policy of how the team operates, such as changes to this document, should have agreement of the team without any blocking objections. diff --git a/mdbook-spec/Cargo.lock b/mdbook-spec/Cargo.lock index 1dea1df7..13866cee 100644 --- a/mdbook-spec/Cargo.lock +++ b/mdbook-spec/Cargo.lock @@ -11,81 +11,11 @@ dependencies = [ "memchr", ] -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anstream" -version = "0.6.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" - -[[package]] -name = "anstyle-parse" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" -dependencies = [ - "anstyle", - "windows-sys 0.59.0", -] - [[package]] name = "anyhow" -version = "1.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" - -[[package]] -name = "autocfg" -version = "1.4.0" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "bitflags" @@ -93,41 +23,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bstr" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" -dependencies = [ - "memchr", - "regex-automata", - "serde", -] - -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - -[[package]] -name = "cc" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" -dependencies = [ - "shlex", -] - [[package]] name = "cfg-if" version = "1.0.0" @@ -135,128 +30,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "chrono" -version = "0.4.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "num-traits", - "windows-targets", -] - -[[package]] -name = "clap" -version = "4.5.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" -dependencies = [ - "clap_builder", -] - -[[package]] -name = "clap_builder" -version = "4.5.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", - "terminal_size", -] - -[[package]] -name = "clap_complete" -version = "4.5.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9647a559c112175f17cf724dc72d3645680a883c58481332779192b0d8e7a01" -dependencies = [ - "clap", -] - -[[package]] -name = "clap_lex" -version = "0.7.3" +name = "equivalent" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" - -[[package]] -name = "colorchoice" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cpufeatures" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "dbus" -version = "0.9.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bb21987b9fb1613058ba3843121dd18b163b254d8a6e797e144cbac14d96d1b" -dependencies = [ - "libc", - "libdbus-sys", - "winapi", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "env_filter" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" -dependencies = [ - "log", - "regex", -] - -[[package]] -name = "env_logger" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "humantime", - "log", -] +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" @@ -275,96 +52,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "handlebars" -version = "6.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd4ccde012831f9a071a637b0d4e31df31c0f6c525784b35ae76a9ac6bc1e315" -dependencies = [ - "log", - "num-order", - "pest", - "pest_derive", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "iana-time-zone" -version = "0.1.61" +name = "hashbrown" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" [[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" +name = "indexmap" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ - "cc", + "equivalent", + "hashbrown", ] -[[package]] -name = "is_terminal_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" - [[package]] name = "itoa" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" -[[package]] -name = "js-sys" -version = "0.3.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" -dependencies = [ - "wasm-bindgen", -] - [[package]] name = "libc" version = "0.2.164" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" -[[package]] -name = "libdbus-sys" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72" -dependencies = [ - "cc", - "pkg-config", -] - [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -372,35 +86,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] -name = "log" -version = "0.4.22" +name = "mdbook-core" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "2ef8430ec21b88489dfffd90c0fb9bd3eab96bf7642ef0cab74754b9d2e5b7f6" +dependencies = [ + "anyhow", + "regex", + "serde", + "serde_json", + "toml", + "tracing", +] [[package]] -name = "mdbook" -version = "0.4.43" +name = "mdbook-markdown" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe1f98b8d66e537d2f0ba06e7dec4f44001deec539a2d18bfc102d6a86189148" +checksum = "27f58c1b5686d0add2b513c15401177f84e87742ec381ccd4bfc2216de9a52e8" dependencies = [ - "anyhow", - "chrono", - "clap", - "clap_complete", - "env_logger", - "handlebars", - "log", - "memchr", - "once_cell", - "opener", "pulldown-cmark", "regex", + "tracing", +] + +[[package]] +name = "mdbook-preprocessor" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01f84f2b2ef3ccf2c6dd71255f9d90912cce7d5a5aa32899d033003d2c71f84d" +dependencies = [ + "anyhow", + "mdbook-core", "serde", "serde_json", - "shlex", - "tempfile", - "toml", - "topological-sort", ] [[package]] @@ -408,10 +127,10 @@ name = "mdbook-spec" version = "0.1.2" dependencies = [ "anyhow", - "mdbook", + "mdbook-markdown", + "mdbook-preprocessor", "once_cell", "pathdiff", - "pulldown-cmark", "railroad", "regex", "semver", @@ -426,57 +145,12 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" -[[package]] -name = "normpath" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "num-modular" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" - -[[package]] -name = "num-order" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6" -dependencies = [ - "num-modular", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - [[package]] name = "once_cell" version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" -[[package]] -name = "opener" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0812e5e4df08da354c851a3376fead46db31c2214f849d3de356d774d057681" -dependencies = [ - "bstr", - "dbus", - "normpath", - "windows-sys 0.59.0", -] - [[package]] name = "pathdiff" version = "0.2.2" @@ -484,55 +158,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361" [[package]] -name = "pest" -version = "2.7.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" -dependencies = [ - "memchr", - "thiserror", - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.7.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.7.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pest_meta" -version = "2.7.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" -dependencies = [ - "once_cell", - "pest", - "sha2", -] - -[[package]] -name = "pkg-config" -version = "0.3.31" +name = "pin-project-lite" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "proc-macro2" @@ -545,9 +174,9 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.10.3" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" +checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0" dependencies = [ "bitflags", "memchr", @@ -557,9 +186,9 @@ dependencies = [ [[package]] name = "pulldown-cmark-escape" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd348ff538bc9caeda7ee8cad2d1d48236a1f443c1fa3913c6a02fe0043b1dd3" +checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae" [[package]] name = "quote" @@ -581,9 +210,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.1" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -593,9 +222,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -644,18 +273,28 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.215" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -664,39 +303,26 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.133" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] -name = "sha2" -version = "0.10.8" +name = "serde_spanned" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" dependencies = [ - "cfg-if", - "cpufeatures", - "digest", + "serde_core", ] -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - [[package]] name = "syn" version = "2.0.89" @@ -722,61 +348,74 @@ dependencies = [ ] [[package]] -name = "terminal_size" -version = "0.4.0" +name = "toml" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" +checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" dependencies = [ - "rustix", - "windows-sys 0.59.0", + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", ] [[package]] -name = "thiserror" -version = "1.0.69" +name = "toml_datetime" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" dependencies = [ - "thiserror-impl", + "serde_core", ] [[package]] -name = "thiserror-impl" -version = "1.0.69" +name = "toml_parser" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" dependencies = [ - "proc-macro2", - "quote", - "syn", + "winnow", ] [[package]] -name = "toml" -version = "0.5.11" +name = "toml_writer" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] +checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" [[package]] -name = "topological-sort" -version = "0.2.2" +name = "tracing" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] [[package]] -name = "typenum" -version = "1.17.0" +name = "tracing-attributes" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "ucd-trie" -version = "0.1.7" +name = "tracing-core" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", +] [[package]] name = "unicase" @@ -796,18 +435,6 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - [[package]] name = "walkdir" version = "2.5.0" @@ -818,77 +445,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasm-bindgen" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" -dependencies = [ - "cfg-if", - "once_cell", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - [[package]] name = "winapi-util" version = "0.1.9" @@ -898,21 +454,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets", -] - [[package]] name = "windows-sys" version = "0.52.0" @@ -994,3 +535,9 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" diff --git a/mdbook-spec/Cargo.toml b/mdbook-spec/Cargo.toml index 8bd02e44..c4189709 100644 --- a/mdbook-spec/Cargo.toml +++ b/mdbook-spec/Cargo.toml @@ -11,11 +11,10 @@ default-run = "mdbook-spec" [dependencies] anyhow = "1.0.79" -mdbook = { version = "0.4.36", default-features = false } +mdbook-markdown = "0.5.1" +mdbook-preprocessor = "0.5.1" once_cell = "1.19.0" pathdiff = "0.2.1" -# Try to keep in sync with mdbook. -pulldown-cmark = { version = "0.10.3", default-features = false } railroad = { version = "0.3.2", default-features = false } regex = "1.9.4" semver = "1.0.21" diff --git a/mdbook-spec/src/admonitions.rs b/mdbook-spec/src/admonitions.rs index 8aaf6cf6..da391838 100644 --- a/mdbook-spec/src/admonitions.rs +++ b/mdbook-spec/src/admonitions.rs @@ -10,7 +10,7 @@ //! 4. Update `docs/authoring.md` to show an example of your new admonition. use crate::{Diagnostics, warn_or_err}; -use mdbook::book::Chapter; +use mdbook_preprocessor::book::Chapter; use regex::{Captures, Regex}; use std::sync::LazyLock; diff --git a/mdbook-spec/src/grammar.rs b/mdbook-spec/src/grammar.rs index 8a15c719..b0c2c581 100644 --- a/mdbook-spec/src/grammar.rs +++ b/mdbook-spec/src/grammar.rs @@ -1,7 +1,7 @@ //! Support for rendering the grammar. use crate::{Diagnostics, warn_or_err}; -use mdbook::book::{Book, BookItem, Chapter}; +use mdbook_preprocessor::book::{Book, BookItem, Chapter}; use regex::{Captures, Regex}; use std::collections::{HashMap, HashSet}; use std::fmt::Write; diff --git a/mdbook-spec/src/lib.rs b/mdbook-spec/src/lib.rs index f5799ae0..0feab5ef 100644 --- a/mdbook-spec/src/lib.rs +++ b/mdbook-spec/src/lib.rs @@ -2,10 +2,10 @@ use crate::rules::Rules; use anyhow::{Context, Result, bail}; -use mdbook::BookItem; -use mdbook::book::{Book, Chapter}; -use mdbook::errors::Error; -use mdbook::preprocess::{CmdPreprocessor, Preprocessor, PreprocessorContext}; +use mdbook_preprocessor::book::BookItem; +use mdbook_preprocessor::book::{Book, Chapter}; +use mdbook_preprocessor::errors::Error; +use mdbook_preprocessor::{Preprocessor, PreprocessorContext}; use once_cell::sync::Lazy; use regex::{Captures, Regex}; use semver::{Version, VersionReq}; @@ -26,17 +26,17 @@ static MD_LINK_REFERENCE_DEFINITION: Lazy = pub fn handle_preprocessing() -> Result<(), Error> { let pre = Spec::new(None)?; - let (ctx, book) = CmdPreprocessor::parse_input(io::stdin())?; + let (ctx, book) = mdbook_preprocessor::parse_input(io::stdin())?; let book_version = Version::parse(&ctx.mdbook_version)?; - let version_req = VersionReq::parse(mdbook::MDBOOK_VERSION)?; + let version_req = VersionReq::parse(mdbook_preprocessor::MDBOOK_VERSION)?; if !version_req.matches(&book_version) { eprintln!( "warning: The {} plugin was built against version {} of mdbook, \ but we're being called from version {}", pre.name(), - mdbook::MDBOOK_VERSION, + mdbook_preprocessor::MDBOOK_VERSION, ctx.mdbook_version ); } diff --git a/mdbook-spec/src/rules.rs b/mdbook-spec/src/rules.rs index 8c3e9a3a..4bfec06b 100644 --- a/mdbook-spec/src/rules.rs +++ b/mdbook-spec/src/rules.rs @@ -2,8 +2,7 @@ use crate::test_links::RuleToTests; use crate::{Diagnostics, Spec, warn_or_err}; -use mdbook::BookItem; -use mdbook::book::Book; +use mdbook_preprocessor::book::{Book, BookItem}; use once_cell::sync::Lazy; use regex::{Captures, Regex}; use std::collections::{BTreeMap, HashSet}; diff --git a/mdbook-spec/src/std_links.rs b/mdbook-spec/src/std_links.rs index cbbed3a5..3251194e 100644 --- a/mdbook-spec/src/std_links.rs +++ b/mdbook-spec/src/std_links.rs @@ -2,10 +2,10 @@ use crate::{Diagnostics, bug, warn_or_err}; use anyhow::{Result, bail}; -use mdbook::BookItem; -use mdbook::book::{Book, Chapter}; +use mdbook_markdown::pulldown_cmark::{BrokenLink, CowStr, Event, LinkType, Options, Parser, Tag}; +use mdbook_preprocessor::book::BookItem; +use mdbook_preprocessor::book::{Book, Chapter}; use once_cell::sync::Lazy; -use pulldown_cmark::{BrokenLink, CowStr, Event, LinkType, Options, Parser, Tag}; use regex::Regex; use std::collections::HashMap; use std::fmt::Write as _; @@ -243,6 +243,7 @@ fn run_rustdoc( LinkType::Autolink | LinkType::Email => { bug!("link type should have been filtered {link:?}"); } + LinkType::WikiLink { .. } => panic!("unsupported wikilink"), } } } diff --git a/mdbook-spec/src/test_links.rs b/mdbook-spec/src/test_links.rs index 8f847d58..3f105c3b 100644 --- a/mdbook-spec/src/test_links.rs +++ b/mdbook-spec/src/test_links.rs @@ -1,7 +1,7 @@ //! Handling for linking tests in rust's testsuite to rule identifiers. use crate::{Rules, Spec}; -use mdbook::book::{Book, BookItem}; +use mdbook_preprocessor::book::{Book, BookItem}; use std::collections::HashMap; use std::fmt::Write; use std::path::PathBuf; diff --git a/src/attributes.md b/src/attributes.md index 79b98988..e5d96944 100644 --- a/src/attributes.md +++ b/src/attributes.md @@ -107,6 +107,7 @@ Attributes may be applied to many forms in the language: * [Function][functions], [closure] and [function pointer] parameters accept outer attributes. This includes attributes on variadic parameters denoted with `...` in function pointers and [external blocks][variadic functions]. +* [Inline assembly] template strings and operands accept outer attributes. Only certain attributes are accepted semantically; for details, see [asm.attributes.supported-attributes]. r[attributes.meta] ## Meta item attribute syntax @@ -234,7 +235,7 @@ pub fn f() {} ``` > [!NOTE] -> `rustc` currently recognizes the tools "clippy", "rustfmt", "diagnostic", "miri" and "rust_analyzer". +> `rustc` currently recognizes the tools "clippy", "rustfmt", "diagnostic", "miri", and "rust_analyzer". r[attributes.builtin] ## Built-in attributes index @@ -409,3 +410,4 @@ The following is an index of all built-in attributes. [variadic functions]: items/external-blocks.html#variadic-functions [`diagnostic::on_unimplemented`]: attributes/diagnostics.md#the-diagnosticon_unimplemented-attribute [`diagnostic::do_not_recommend`]: attributes/diagnostics.md#the-diagnosticdo_not_recommend-attribute +[Inline assembly]: inline-assembly.md diff --git a/src/attributes/codegen.md b/src/attributes/codegen.md index d472c4db..7eb98daf 100644 --- a/src/attributes/codegen.md +++ b/src/attributes/codegen.md @@ -578,6 +578,30 @@ Feature | Implicitly Enables | Description [tail-call]: https://github.com/webassembly/tail-call [multivalue]: https://github.com/webassembly/multi-value +r[attributes.codegen.target_feature.s390x] +#### `s390x` + +On `s390x` targets, use of functions with the `#[target_feature]` attribute follows the [above restrictions][attributes.codegen.target_feature.safety-restrictions]. + +Further documentation on these features can be found in the "Additions to z/Architecture" section of Chapter 1 of the *[z/Architecture Principles of Operation]*. + +Feature | Implicitly Enables | Description +---------------------------------------|---------------------------------------|--------------------- +`vector` | | 128-bit vector instructions +`vector-enhancements-1` | `vector` | vector enhancements 1 +`vector-enhancements-2` | `vector-enhancements-1` | vector enhancements 2 +`vector-enhancements-3` | `vector-enhancements-2` | vector enhancements 3 +`vector-packed-decimal` | `vector` | vector packed-decimal +`vector-packed-decimal-enhancement` | `vector-packed-decimal` | vector packed-decimal enhancement +`vector-packed-decimal-enhancement-2` | `vector-packed-decimal-enhancement-2` | vector packed-decimal enhancement 2 +`vector-packed-decimal-enhancement-3` | `vector-packed-decimal-enhancement-3` | vector packed-decimal enhancement 3 +`nnp-assist` | `vector` | nnp assist +`miscellaneous-extensions-2` | | miscellaneous extensions 2 +`miscellaneous-extensions-3` | | miscellaneous extensions 3 +`miscellaneous-extensions-4` | | miscellaneous extensions 4 + +[z/Architecture Principles of Operation]: https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf + r[attributes.codegen.target_feature.info] ### Additional information @@ -588,8 +612,7 @@ that this option is not affected by the `target_feature` attribute, and is only driven by the features enabled for the entire crate. r[attributes.codegen.target_feature.remark-rt] -See the [`is_x86_feature_detected`] or [`is_aarch64_feature_detected`] macros -in the standard library for runtime feature detection on these platforms. +Whether a feature is enabled can be checked at runtime using a platform-specific macro from the standard library, for instance [`is_x86_feature_detected`] or [`is_aarch64_feature_detected`]. > [!NOTE] > `rustc` has a default set of features enabled for each target and CPU. The CPU may be chosen with the [`-C target-cpu`] flag. Individual features may be enabled or disabled for an entire crate with the [`-C target-feature`] flag. diff --git a/src/const_eval.md b/src/const_eval.md index 7cb85dc2..71f392dc 100644 --- a/src/const_eval.md +++ b/src/const_eval.md @@ -55,7 +55,7 @@ r[const-eval.const-expr.array] * [Array expressions]. r[const-eval.const-expr.constructor] -* [Struct] expressions. +* [Struct expressions]. r[const-eval.const-expr.block] * [Block expressions], including `unsafe` and `const` blocks. @@ -203,7 +203,23 @@ r[const-eval.const-expr.borrows] > See [issue #143129](https://github.com/rust-lang/rust/issues/143129) for more details. r[const-eval.const-expr.deref] -* The [dereference operator] except for raw pointers. +* [Dereference expressions]. + + ```rust,no_run + # use core::cell::UnsafeCell; + const _: u8 = unsafe { + let x: *mut u8 = &raw mut *&mut 0; + // ^^^^^^^ + // Dereference of mutable reference. + *x = 1; // Dereference of mutable pointer. + *(x as *const u8) // Dereference of constant pointer. + }; + const _: u8 = unsafe { + let x = &UnsafeCell::new(0); + *x.get() = 1; // Mutation of interior mutable value. + *x.get() + }; + ``` r[const-eval.const-expr.group] @@ -304,8 +320,8 @@ The types of a const function's parameters and return type are restricted to tho [constant expressions]: #constant-expressions [constants]: items/constant-items.md [Const parameters]: items/generics.md -[dereference expression]: expressions/operator-expr.md#the-dereference-operator -[dereference operator]: expressions/operator-expr.md#the-dereference-operator +[dereference expression]: expr.deref +[dereference expressions]: expr.deref [destructors]: destructors.md [enum discriminants]: items/enumerations.md#discriminants [expression statements]: statements.md#expression-statements @@ -332,7 +348,7 @@ The types of a const function's parameters and return type are restricted to tho [range expressions]: expressions/range-expr.md [slice]: types/slice.md [statics]: items/static-items.md -[struct]: expressions/struct-expr.md +[Struct expressions]: expressions/struct-expr.md [temporary lifetime extension]: destructors.scope.lifetime-extension [tuple enum variant]: items/enumerations.md [tuple expressions]: expressions/tuple-expr.md diff --git a/src/expressions/operator-expr.md b/src/expressions/operator-expr.md index fae78dd4..0ea7ee0b 100644 --- a/src/expressions/operator-expr.md +++ b/src/expressions/operator-expr.md @@ -378,7 +378,7 @@ The operands of all of these operators are evaluated in [value expression contex | `/` | Division*† | | Division | `std::ops::Div` | `std::ops::DivAssign` | | `%` | Remainder**† | | Remainder | `std::ops::Rem` | `std::ops::RemAssign` | | `&` | Bitwise AND | [Logical AND] | | `std::ops::BitAnd` | `std::ops::BitAndAssign` | -| | | Bitwise OR | [Logical OR] | | `std::ops::BitOr` | `std::ops::BitOrAssign` | +| `\|` | Bitwise OR | [Logical OR] | | `std::ops::BitOr` | `std::ops::BitOrAssign` | | `^` | Bitwise XOR | [Logical XOR] | | `std::ops::BitXor` | `std::ops::BitXorAssign` | | `<<` | Left Shift | | | `std::ops::Shl` | `std::ops::ShlAssign` | | `>>` | Right Shift*** | | | `std::ops::Shr` | `std::ops::ShrAssign` | diff --git a/src/glossary.md b/src/glossary.md index fd865dcc..c6c1656b 100644 --- a/src/glossary.md +++ b/src/glossary.md @@ -1,5 +1,6 @@ # Glossary +r[glossary.ast] ### Abstract syntax tree An ‘abstract syntax tree’, or ‘AST’, is an intermediate representation of diff --git a/src/inline-assembly.md b/src/inline-assembly.md index 41bff252..b08ad410 100644 --- a/src/inline-assembly.md +++ b/src/inline-assembly.md @@ -49,15 +49,19 @@ r[asm.syntax] The following grammar specifies the arguments that can be passed to the `asm!`, `global_asm!` and `naked_asm!` macros. ```grammar,assembly -@root AsmArgs -> FormatString (`,` FormatString)* (`,` AsmOperand)* `,`? +@root AsmArgs -> AsmAttrFormatString (`,` AsmAttrFormatString)* (`,` AsmAttrOperand)* `,`? FormatString -> STRING_LITERAL | RAW_STRING_LITERAL | MacroInvocation +AsmAttrFormatString -> (OuterAttribute)* FormatString + AsmOperand -> ClobberAbi | AsmOptions | RegOperand +AsmAttrOperand -> (OuterAttribute)* AsmOperand + ClobberAbi -> `clobber_abi` `(` Abi (`,` Abi)* `,`? `)` AsmOptions -> @@ -266,6 +270,44 @@ Further constraints on the directives used by inline assembly are indicated by [ [format-syntax]: std::fmt#syntax [rfc-2795]: https://github.com/rust-lang/rfcs/pull/2795 +r[asm.attributes] +## Attributes + +r[asm.attributes.supported-attributes] +Only the [`cfg`] and [`cfg_attr`] attributes are accepted semantically on inline assembly template strings and operands. Other attributes are parsed but rejected when the assembly macro is expanded. + +```rust +# fn main() {} +# #[cfg(target_arch = "x86_64")] +core::arch::global_asm!( + #[cfg(not(panic = "abort"))] + ".cfi_startproc", + // ... + "ret", + #[cfg(not(panic = "abort"))] + ".cfi_endproc", +); +``` + +> [!NOTE] +> In `rustc`, the assembly macros implement handling of these attributes separately from the normal system that handles similar attributes in the language. This accounts for the limited kinds of attributes supported and may give rise to subtle differences in behavior. + +r[asm.attributes.starts-with-template] +Syntactically there must be at least one template string before the first operand. + +```rust,compile_fail +// This is rejected because `a = out(reg) x` does not parse as a +// template string. +core::arch::asm!( + #[cfg(false)] + a = out(reg) x, // ERROR. + "", +); +``` + +[`cfg`]: conditional-compilation.md#the-cfg-attribute +[`cfg_attr`]: conditional-compilation.md#the-cfg_attr-attribute + r[asm.operand-type] ## Operand type diff --git a/src/items/constant-items.md b/src/items/constant-items.md index 321894a9..0b2f223c 100644 --- a/src/items/constant-items.md +++ b/src/items/constant-items.md @@ -48,137 +48,6 @@ const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings { }; ``` -r[items.const.no-mut-refs] -The final value of a `const` item, after the initializer is evaluated to a value that has the declared type of the constant, cannot contain any mutable references except as described below. - -```rust -# #![allow(static_mut_refs)] -static mut S: u8 = 0; -const _: &u8 = unsafe { &mut S }; // OK. -// ^^^^^^ -// Allowed since this is coerced to `&S`. -``` - -```rust -# use core::sync::atomic::AtomicU8; -static S: AtomicU8 = AtomicU8::new(0); -const _: &AtomicU8 = &S; // OK. -// ^^ -// Allowed even though the shared reference is to an interior -// mutable value. -``` - -```rust,compile_fail,E0080 -# #![allow(static_mut_refs)] -static mut S: u8 = 0; -const _: &mut u8 = unsafe { &mut S }; // ERROR. -// ^^^^^^ -// Not allowed as the mutable reference appears in the final value. -``` - -> [!NOTE] -> Constant initializers can be thought of, in most cases, as being inlined wherever the constant appears. If a constant whose value contains a mutable reference to a mutable static were to appear twice, and this were to be allowed, that would create two mutable references, each having `'static` lifetime, to the same place. This could produce undefined behavior. -> -> Constants that contain mutable references to temporaries whose scopes have been extended to the end of the program have that same problem and an additional one. -> -> ```rust,compile_fail,E0764 -> const _: &mut u8 = &mut 0; // ERROR. -> // ^^^^^^ -> // Not allowed as the mutable reference appears in the final value and -> // because the constant expression contains a mutable borrow of an -> // expression whose temporary scope would be extended to the end of -> // the program. -> ``` -> -> Here, the value `0` is a temporary whose scope is extended to the end of the program (see [destructors.scope.lifetime-extension.static]). Such temporaries cannot be mutably borrowed in constant expressions (see [const-eval.const-expr.borrows]). -> -> To allow this, we'd have to decide whether each use of the constant creates a new `u8` value or whether each use shares the same lifetime-extended temporary. The latter choice, though closer to how `rustc` thinks about this today, would break the conceptual model that, in most cases, the constant initializer can be thought of as being inlined wherever the constant is used. Since we haven't decided, and due to the other problem mentioned, this is not allowed. - -```rust,compile_fail,E0080 -# #![allow(static_mut_refs)] -static mut S: u8 = 0; -const _: &dyn Send = &unsafe { &mut S }; // ERROR. -// ^^^^^^ -// Not allowed as the mutable reference appears in the final value, -// even though type erasure occurs. -``` - -Mutable references where the referent is a value of a [zero-sized type] are allowed. - -```rust -# #![allow(static_mut_refs)] -static mut S: () = (); -const _: &mut () = unsafe { &mut S }; // OK. -// ^^ This is a zero-sized type. -``` - -```rust -# #![allow(static_mut_refs)] -static mut S: [u8; 0] = [0; 0]; -const _: &mut [u8; 0] = unsafe { &mut S }; // OK. -// ^^^^^^^ This is a zero-sized type. -``` - -> [!NOTE] -> This is allowed as, for a value of a zero-sized type, no bytes can actually be mutated. We must accept this as `&mut []` is [promoted]. - -Values of [union type] are not considered to contain any references; for this purpose, a value of union type is treated as a sequence of untyped bytes. - -```rust -# #![allow(static_mut_refs)] -union U { f: &'static mut u8 } -static mut S: u8 = 0; -const _: U = unsafe { U { f: &mut S }}; // OK. -// ^^^^^^^^^^^^^^^ -// This is treated as a sequence of untyped bytes. -``` - -Mutable references contained within a [mutable static] may be referenced in the final value of a constant. - -```rust -# #![allow(static_mut_refs)] -static mut S: &mut u8 = unsafe { static mut I: u8 = 0; &mut I }; -const _: &&mut u8 = unsafe { &S }; // OK. -// ^^^^^^^ -// This mutable reference comes from a `static mut`. -``` - -> [!NOTE] -> This is allowed as it's separately not allowed to read from a mutable static during constant evaluation. See [const-eval.const-expr.path-static]. - -Mutable references contained within an [external static] may be referenced in the final value of a constant. - -```rust -# #![allow(static_mut_refs)] -unsafe extern "C" { static S: &'static mut u8; } -const _: &&mut u8 = unsafe { &S }; // OK. -// ^^^^^^^ -// This mutable references comes from an extern static. -``` - -> [!NOTE] -> This is allowed as it's separately not allowed to read from an external static during constant evaluation. See [const-eval.const-expr.path-static]. - -> [!NOTE] -> As described above, we accept, in the final value of constant items, shared references to static items whose values have interior mutability. -> -> ```rust -> # use core::sync::atomic::AtomicU8; -> static S: AtomicU8 = AtomicU8::new(0); -> const _: &AtomicU8 = &S; // OK. -> ``` -> -> However, we disallow similar code when the interior mutable value is created in the initializer. -> -> ```rust,compile_fail,E0492 -> # use core::sync::atomic::AtomicU8; -> const _: &AtomicU8 = &AtomicU8::new(0); // ERROR. -> ``` -> -> Here, the `AtomicU8` is a temporary whose scope is extended to the end of the program (see [destructors.scope.lifetime-extension.static]). Such temporaries with interior mutability cannot be borrowed in constant expressions (see [const-eval.const-expr.borrows]). -> -> To allow this, we'd have to decide whether each use of the constant creates a new `AtomicU8` or whether each use shares the same lifetime-extended temporary. The latter choice, though closer to how `rustc` thinks about this today, would break the conceptual model that, in most cases, the constant initializer can be thought of as being inlined wherever the constant is used. Since we haven't decided, this is not allowed. - r[items.const.expr-omission] The constant expression may only be omitted in a [trait definition]. @@ -254,15 +123,10 @@ fn unused_generic_function() { [const_eval]: ../const_eval.md [associated constant]: ../items/associated-items.md#associated-constants [constant value]: ../const_eval.md#constant-expressions -[external static]: items.extern.static [free]: ../glossary.md#free-item [static lifetime elision]: ../lifetime-elision.md#const-and-static-elision [trait definition]: traits.md [underscore imports]: use-declarations.md#underscore-imports [`Copy`]: ../special-types-and-traits.md#copy [value namespace]: ../names/namespaces.md -[mutable static]: items.static.mut -[promoted]: destructors.scope.const-promotion [promotion]: destructors.scope.const-promotion -[union type]: type.union -[zero-sized type]: layout.properties.size diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index c360189b..b3a1d2fe 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -124,7 +124,7 @@ r[items.extern.abi.c] * `unsafe extern "C"` --- The "C" ABI matches the default ABI chosen by the dominant C compiler for the target. r[items.extern.abi.system] -* `unsafe extern "system"` --- This is equivalent to `extern "C"` except on Windows x86_32 where it is equivalent to `"stdcall"`. +* `unsafe extern "system"` --- This is equivalent to `extern "C"` except on Windows x86_32 where it is equivalent to `"stdcall"` for non-variadic functions, and equivalent to `"C"` for variadic functions. > [!NOTE] > As the correct underlying ABI on Windows is target-specific, it's best to use `extern "system"` when attempting to link Windows API functions that don't use an explicitly defined ABI. @@ -257,6 +257,7 @@ Variadic parameters can only be specified within `extern` blocks with the follow - `"C"` - `"cdecl"` - `"efiapi"` +- `"system"` - `"sysv64"` - `"win64"` diff --git a/src/items/use-declarations.md b/src/items/use-declarations.md index 94638b6a..71661d6c 100644 --- a/src/items/use-declarations.md +++ b/src/items/use-declarations.md @@ -116,6 +116,7 @@ They may create bindings for: * [Built-in types] * [Attributes] * [Derive macros] +* [`macro_rules`] r[items.use.path.disallowed] They cannot import [associated items], [generic parameters], [local variables], paths with [`Self`], or [tool attributes]. More restrictions are described below. @@ -302,6 +303,10 @@ mod clashing { } ``` +> [!NOTE] +> +> For areas where shadowing is not allowed, see [name resolution ambiguities]. + r[items.use.glob.last-segment-only] `*` cannot be used as the first or intermediate segments. @@ -389,71 +394,19 @@ r[items.use.restrictions.variant] use TypeAlias::MyVariant; //~ ERROR ``` -r[items.use.ambiguities] -## Ambiguities - -> [!NOTE] -> This section is incomplete. - -r[items.use.ambiguities.intro] -Some situations are an error when there is an ambiguity as to which name a `use` declaration refers. This happens when there are two name candidates that do not resolve to the same entity. - -r[items.use.ambiguities.glob] -Glob imports are allowed to import conflicting names in the same namespace as long as the name is not used. -For example: - -```rust -mod foo { - pub struct Qux; -} - -mod bar { - pub struct Qux; -} - -use foo::*; -use bar::*; //~ OK, no name conflict. - -fn main() { - // This would be an error, due to the ambiguity. - //let x = Qux; -} -``` - -Multiple glob imports are allowed to import the same name, and that name is allowed to be used, if the imports are of the same item (following re-exports). The visibility of the name is the maximum visibility of the imports. For example: - -```rust -mod foo { - pub struct Qux; -} - -mod bar { - pub use super::foo::Qux; -} - -// These both import the same `Qux`. The visibility of `Qux` -// is `pub` because that is the maximum visibility between -// these two `use` declarations. -pub use bar::*; -use foo::*; - -fn main() { - let _: Qux = Qux; -} -``` - -[`extern crate`]: extern-crates.md -[`macro_rules`]: ../macros-by-example.md -[`self`]: ../paths.md#self -[associated items]: associated-items.md [Attributes]: ../attributes.md [Built-in types]: ../types.md [Derive macros]: macro.proc.derive [Enum variants]: enumerations.md +[`extern crate`]: extern-crates.md +[`macro_rules`]: ../macros-by-example.md +[`self`]: ../paths.md#self +[associated items]: associated-items.md [extern prelude]: ../names/preludes.md#extern-prelude [generic parameters]: generics.md [items]: ../items.md [local variables]: ../variables.md +[name resolution ambiguities]: names.resolution.expansion.imports.ambiguity [namespace]: ../names/namespaces.md [namespaces]: ../names/namespaces.md [paths]: ../paths.md diff --git a/src/macros-by-example.md b/src/macros-by-example.md index 2fa104ed..64a89286 100644 --- a/src/macros-by-example.md +++ b/src/macros-by-example.md @@ -326,6 +326,77 @@ fn foo() { // m!(); // Error: m is not in scope. ``` +r[macro.decl.scope.textual.shadow.path-based] +Textual scope name bindings for macros shadow path-based scope bindings to macros. + +```rust +#[macro_export] +macro_rules! m2 { + () => { + println!("m2"); + }; +} + +m!(); // prints "m2\n" + +macro_rules! m { + () => { + println!("m"); + }; +} + +use crate::m2 as m; + +m!(); // prints "m\n" +``` + +> [!NOTE] +> +> For areas where shadowing is not allowed, see [name resolution ambiguities]. + +r[macro.decl.scope.path-based] +### Path-based scope + +r[macro.decl.scope.path-based.intro] +By default, a macro has no path-based scope. Macros can gain path-based scope in two ways: + +* [Use declaration re-export] +* [`macro_export`] + +r[macro.decl.scope.path.reexport] +Macros can be re-exported to give them path-based scope from a module other than the crate root. + +```rust +mac::m!(); // OK: Path-based lookup finds m in the mac module. + +mod mac { + macro_rules! m { + () => {}; + } + pub(crate) use m; +} +``` + +r[macro.decl.scope.path-based.visibility] +Macros have an implicit visibility of `pub(crate)`. `#[macro_export]` changes the implicit visibility to `pub`. + +```rust,compile_fail,E0364 +macro_rules! private_m { + () => {}; +} + +#[macro_export] +macro_rules! pub_m { + () => {}; +} + +pub(crate) use private_m as private_macro; // OK +pub use pub_m as pub_macro; // OK + +pub use private_m; // ERROR: `private_m` is only public within + // the crate and cannot be re-exported outside +``` + r[macro.decl.scope.macro_use] ### The `macro_use` attribute @@ -713,14 +784,17 @@ expansions, taking separators into account. This means: For more detail, see the [formal specification]. +[Hygiene]: #hygiene +[Metavariables]: #metavariables +[Repetitions]: #repetitions +[Use declaration re-export]: items/use-declarations.md#use-visibility +[`macro_export`]: #the-macro_export-attribute +[`$crate`]: macro.decl.hygiene.crate [`extern crate self`]: items.extern-crate.self [`macro_use` prelude]: names/preludes.md#macro_use-prelude [block labels]: expr.loop.block-labels [delimiters]: tokens.md#delimiters [formal specification]: macro-ambiguity.md -[Hygiene]: #hygiene [loop labels]: expressions/loop-expr.md#loop-labels -[Metavariables]: #metavariables -[Repetitions]: #repetitions +[name resolution ambiguities]: names/name-resolution.md#r-names.resolution.expansion.imports.ambiguity [token]: tokens.md -[`$crate`]: macro.decl.hygiene.crate diff --git a/src/macros.md b/src/macros.md index 36287e0d..1cd90203 100644 --- a/src/macros.md +++ b/src/macros.md @@ -106,15 +106,25 @@ macro_rules! example { example!(); ``` +r[macro.invocation.name-resolution] + +Macros invocations can be resolved via two kinds of scopes: + +* Textual Scope + * [Textual scope `macro_rules`](macros-by-example.md#r-macro.decl.scope.textual) +* Path-based scope + * [Path-based scope `macro_rules`](macros-by-example.md#r-macro.decl.scope.path-based) + * [Procedural macros] + +[External blocks]: items/external-blocks.md [Macros by Example]: macros-by-example.md [Procedural Macros]: procedural-macros.md +[`macro_rules`]: macros-by-example.md [associated items]: items/associated-items.md [delimiters]: tokens.md#delimiters [expressions]: expressions.md [items]: items.md -[`macro_rules`]: macros-by-example.md [patterns]: patterns.md [statements]: statements.md [types]: types.md [visibility qualifiers]: visibility-and-privacy.md -[External blocks]: items/external-blocks.md diff --git a/src/names/name-resolution.md b/src/names/name-resolution.md index da60d7eb..c22476af 100644 --- a/src/names/name-resolution.md +++ b/src/names/name-resolution.md @@ -1,4 +1,420 @@ +r[names.resolution] # Name resolution +r[names.resolution.intro] +_Name resolution_ is the process of tying paths and other identifiers to the declarations of those entities. Names are segregated into different [namespaces], allowing entities in different namespaces to share the same name without conflict. Each name is valid within a [scope], or a region of source text where that name may be referenced. Access to a name may be restricted based on its [visibility]. + +Name resolution is split into three stages throughout the compilation process. The first stage, *expansion-time resolution*, resolves all [`use` declarations] and [macro invocations]. The second stage, *primary resolution*, resolves all names that have not yet been resolved and that do not depend on type information to resolve. The last stage, *type-relative resolution*, resolves the remaining names once type information is available. + +> [!NOTE] +> Expansion-time resolution is also known as *early resolution*. Primary resolution is also known as *late resolution*. + +r[names.resolution.general] +## General + +r[names.resolution.general.intro] +The rules within this section apply to all stages of name resolution. + +r[names.resolution.general.scopes] +### Scopes + +r[names.resolution.general.scopes.intro] > [!NOTE] -> This is a placeholder for future expansion. +> This is a placeholder for future expansion about resolution of names within various scopes. + +r[names.resolution.expansion] +## Expansion-time name resolution + +r[names.resolution.expansion.intro] +Expansion-time name resolution is the stage of name resolution necessary to complete macro expansion and fully generate a crate's [AST]. This stage requires the resolution of macro invocations and `use` declarations. Resolving `use` declarations is required for macro invocations that resolve via [path-based scope]. Resolving macro invocations is required in order to expand them. + +r[names.resolution.expansion.unresolved-invocations] +After expansion-time name resolution, the AST must not contain any unexpanded macro invocations. Every macro invocation resolves to a valid definition that exists in the final AST or in an external crate. + +```rust,compile_fail +m!(); // ERROR: Cannot find macro `m` in this scope. +``` + +r[names.resolution.expansion.expansion-order-stability] +The resolution of names must be stable. After expansion, names in the fully expanded AST must resolve to the same definition regardless of the order in which macros are expanded and imports are resolved. + +r[names.resolution.expansion.speculation] +All name resolution candidates selected during macro expansion are considered speculative. Once the crate has been fully expanded, all speculative import resolutions are validated to ensure that macro expansion did not introduce any new ambiguities. + +> [!NOTE] +> Due to the iterative nature of macro expansion, this causes so-called time traveling ambiguities, such as when a macro or glob import introduces an item that is ambiguous with its own base path. +> +> ```rust,compile_fail,E0659 +> # fn main() {} +> macro_rules! f { +> () => { +> mod m { +> pub(crate) use f; +> } +> } +> } +> f!(); +> +> const _: () = { +> // Initially, we speculatively resolve `m` to the module in +> // the crate root. +> // +> // Expansion of `f` introduces a second `m` module inside this +> // body. +> // +> // Expansion-time resolution finalizes resolutions by re- +> // resolving all imports and macro invocations, sees the +> // introduced ambiguity and reports it as an error. +> m::f!(); // ERROR: `m` is ambiguous. +> }; +> ``` + +r[names.resolution.expansion.imports] +### Imports +r[names.resolution.expansion.imports.intro] +All `use` declarations are fully resolved during this stage of resolution. [Type-relative paths] cannot be resolved at this stage and will produce an error. + +```rust +mod m { + pub const C: () = (); + pub enum E { V } + pub type A = E; + impl E { + pub const C: () = (); + } +} + +// Valid imports resolved at expansion-time: +use m::C; // OK. +use m::E; // OK. +use m::A; // OK. +use m::E::V; // OK. + +// Valid expressions resolved during type-relative resolution: +let _ = m::A::V; // OK. +let _ = m::E::C; // OK. +``` + +```rust,compile_fail,E0432 +# mod m { +# pub const C: () = (); +# pub enum E { V } +# pub type A = E; +# impl E { +# pub const C: () = (); +# } +# } +// Invalid type-relative imports that can't resolve at expansion-time: +use m::E::C; // ERROR: Unresolved import `m::E::C`. +use m::A::V; // ERROR: Unresolved import `m::A::V`. +``` + +r[names.resolution.expansion.imports.shadowing] +Names introduced via `use` declarations in an [outer scope] are shadowed by +candidates in the same namespace with the same name from an inner scope except +where otherwise restricted by [name resolution ambiguities]. + +```rust +pub mod foo { + pub mod baz { + pub struct Name; + } +} + +pub mod bar { + pub mod baz { + pub struct Name(pub ()); + } +} + +use foo::baz; +fn f() { + use bar::baz; + use baz::Name + Name(()); +} +``` + +r[names.resolution.expansion.imports.shadowing.shared-scope] +Shadowing of names introduced via `use` declarations within a single scope is permitted in the following situations: + +- [`use` glob shadowing] +- [Macro textual scope shadowing] + +r[names.resolution.expansion.imports.ambiguity] +#### Ambiguities + +r[names.resolution.expansion.imports.ambiguity.intro] +Some situations are an error when there is an ambiguity as to which macro definition, `use` declaration, or module an import or macro invocation's name refers to. This happens when there are two name candidates that do not resolve to the same entity where neither candidate is [permitted] to shadow the other. + +r[names.resolution.expansion.imports.ambiguity.glob-vs-glob] +Names may not be resolved through ambiguous glob imports. Glob imports are allowed to import conflicting names in the same namespace as long as the name is not used. Names with conflicting candidates from ambiguous glob imports may still be shadowed by non glob imports and used without producing an error. The errors occur at time of use, not time of import. + +For example: + +```rust +mod foo { + pub struct Qux; +} + +mod bar { + pub struct Qux; +} + +use foo::*; +use bar::*; // OK, no name conflict. + +fn ambiguous_use() { + // This would be an error, due to the ambiguity. + //let x = Qux; +} + +fn ambiguous_shadow() { + // This is permitted, since resolution is not through the ambiguous globs. + struct Qux; + let x = Qux; +} +``` + +Multiple glob imports are allowed to import the same name, and that name is allowed to be used if the imports are of the same item (following re-exports). The visibility of the name is the maximum visibility of the imports. For example: + +```rust +mod foo { + pub struct Qux; +} + +mod bar { + pub use super::foo::Qux; +} + +// These both import the same `Qux`. The visibility of `Qux` +// is `pub` because that is the maximum visibility between +// these two `use` declarations. +pub use bar::*; +use foo::*; + +fn main() { + let _: Qux = Qux; +} +``` + +r[names.resolution.expansion.imports.ambiguity.glob-vs-outer] +Names may not be resolved through glob imports when there is another candidate available in an [outer scope]. + +```rust,compile_fail,E0659 +mod bar { + pub mod foo { +// ^-- glob `foo` candidate + pub struct Name; + } +} + +pub mod foo { +// ^-- outer `foo` candidate + pub struct Name; +} + +pub fn qux() { + use bar::*; + use foo::Name; // ERROR: `foo` is ambiguous +} +``` + +```rust,compile_fail,E0659 +pub mod bar { + #[macro_export] + macro_rules! m { + () => {}; + } + + macro_rules! m2 { + () => {}; + } + pub(crate) use m2 as m; +} + +pub fn qux() { + use bar::*; + m!(); // ERROR: `m` is ambiguous +} +``` + +> [!NOTE] +> These ambiguity errors are specific to imports, even though they are only observed when those imports are used. Having multiple candidates available for a given name during later stages of resolution is not considered an error. So long as none of the imports themselves are ambiguous, there will always be a single unambiguous closest resolution. +> +> ```rust +> mod bar { +> pub const NAME: bool = true; +> } +> +> mod baz { +> pub const NAME: bool = false; +> } +> +> use baz::NAME; +> +> pub fn foo() { +> use bar::*; +> assert!(NAME); +> // ^--- This `NAME` is resolved during primary resolution. +> } +> ``` + +r[names.resolution.expansion.imports.ambiguity.path-vs-textual-macro] +Path-based scope bindings for macros may not shadow textual scope bindings to macros. + +```rust,compile_fail,E0659 +macro_rules! m2 { + () => {} +} +macro_rules! m { + () => {} +} +pub fn foo() { + m!(); // ERROR: `m` is ambiguous + use m2 as m; // In scope for entire function body. +} +``` + +r[names.resolution.expansion.macros] +### Macros + +r[names.resolution.expansion.macros.intro] +Macros are resolved by iterating through the available scopes to find the available candidates. Macros are split into two sub-namespaces, one for bang macros, and the other for attributes and derives. Resolution candidates from the incorrect sub-namespace are ignored. + +r[names.resolution.expansion.macros.visitation-order] +The available scopes are visited in the following order. + +* [Derive helpers] +* [Textual scope macros] +* [Path-based scope macros] +* [`macro_use` prelude] +* [Standard library prelude] +* [Builtin attributes] + +> [!NOTE] +> +> The compiler will attempt to resolve derive helpers that are used before their associated macro introduces them into scope. This scope is visited after the scope for resolving derive helper candidates that are correctly in scope. This behavior is slated for removal. +> +> For more info see [derive helper scope]. + +> [!EDITION-2018] +> +> Starting in edition 2018 the `#[macro_use]` prelude is not visited when `#[no_implicit_prelude]` is present. + +r[names.resolution.expansion.macros.derivehelpers] +Derive helper scopes are not visited when resolving derive macros in the parent scope (starting scope). + +r[names.resolution.expansion.macros.reserved-names] +The names `cfg` and `cfg_attr` are reserved in the macro attribute [sub-namespace]. + +r[names.resolution.expansion.macros.ambiguity] +#### Ambiguities + +r[names.resolution.expansion.macros.ambiguity.more-expanded-vs-outer] +Name bindings from macro expansions may not shadow name bindings from outside of those expansions. + +```rust,compile_fail,E0659 +macro_rules! name { + () => {} +} + +macro_rules! define_name { + () => { + macro_rules! name { + () => {} + } + } +} + +fn foo() { + define_name!(); + name!(); // ERROR: `name` is ambiguous +} +``` + +r[names.resolution.expansion.macros.ambiguity.builtin-attr] +User defined attributes or derive macros may not shadow builtin non-macro attributes (e.g. inline). + + +```rust,ignore +// with-helper/src/lib.rs +# use proc_macro::TokenStream; +# +#[proc_macro_derive(WithHelperAttr, attributes(non_exhaustive))] +// ^------------- user attr candidate +... +# pub fn derive_with_helper_attr(_item: TokenStream) -> TokenStream { +# TokenStream::new() +# } +``` + + +```rust,ignore +// src/lib.rs +#[derive(with_helper::WithHelperAttr)] +#[non_exhaustive] // ERROR: `non_exhaustive` is ambiguous +struct S; +``` + +> [!NOTE] +> This applies regardless of the name the builtin attribute is a candidate for: +> +> +> ```rust,ignore +> // with-helper/src/lib.rs +> # use proc_macro::TokenStream; +> # +> #[proc_macro_derive(WithHelperAttr, attributes(helper))] +> // ^----- user attr candidate +> ... +> # pub fn derive_with_helper_attr(_item: TokenStream) -> TokenStream { +> # TokenStream::new() +> # } +> ``` +> +> +> ```rust,ignore +> // src/lib.rs +> use inline as helper; +> // ^----- builtin attr candidate via re-export +> +> #[derive(with_helper::WithHelperAttr)] +> #[helper] // ERROR: `helper` is ambiguous +> struct S; +> ``` + +r[names.resolution.primary] +## Primary name resolution +> [!NOTE] +> This is a placeholder for future expansion about primary name resolution. + +r[names.resolution.type-relative] +# Type-relative resolution +> [!NOTE] +> This is a placeholder for future expansion about type-dependent resolution. + +[AST]: glossary.ast +[Builtin attributes]: ./preludes.md#r-names.preludes.lang +[Derive helpers]: ../procedural-macros.md#r-macro.proc.derive.attributes +[Macros]: ../macros.md +[Path-based scope macros]: ../macros.md#r-macro.invocation.name-resolution +[Standard library prelude]: ./preludes.md#r-names.preludes.std +[Textual scope macros]: ../macros-by-example.md#r-macro.decl.scope.textual +[`let` bindings]: ../statements.md#let-statements +[`macro_use` prelude]: ./preludes.md#r-names.preludes.macro_use +[`use` declarations]: ../items/use-declarations.md +[`use` glob shadowing]: ../items/use-declarations.md#r-items.use.glob.shadowing +[derive helper scope]: ../procedural-macros.md#r-macro.proc.derive.attributes.scope +[item definitions]: ../items.md +[macro invocations]: ../macros.md#macro-invocation +[macro textual scope shadowing]: ../macros-by-example.md#r-macro.decl.scope.textual.shadow +[name resolution ambiguities]: #r-names.resolution.expansion.imports.ambiguity +[namespaces]: ../names/namespaces.md +[outer scope]: #r-names.resolution.general.scopes +[path-based scope]: ../macros.md#r-macro.invocation.name-resolution +[permitted]: name-resolution.md#r-names.resolution.expansion.imports.shadowing +[scope]: ../names/scopes.md +[sub-namespace]: ../names/namespaces.md#r-names.namespaces.sub-namespaces +[type-relative paths]: names.resolution.type-relative +[visibility]: ../visibility-and-privacy.md diff --git a/src/names/namespaces.md b/src/names/namespaces.md index b3560d2c..c0156fc4 100644 --- a/src/names/namespaces.md +++ b/src/names/namespaces.md @@ -117,58 +117,70 @@ This prevents one style from shadowing another. For example, the [`cfg` attribute] and the [`cfg` macro] are two different entities with the same name in the macro namespace, but they can still be used in their respective context. -r[names.namespaces.sub-namespaces.use-shadow] -It is still an error for a [`use` import] to shadow another macro, regardless of their sub-namespaces. + +> [!NOTE] +> `use` imports still cannot create duplicate bindings of the same name in a module or block, regardless of sub-namespace. +> +> ```rust,ignore +> #[macro_export] +> macro_rules! mymac { +> () => {}; +> } +> +> use myattr::mymac; // error[E0252]: the name `mymac` is defined multiple times +> ``` -[`cfg` attribute]: ../conditional-compilation.md#the-cfg-attribute -[`cfg` macro]: ../conditional-compilation.md#the-cfg-macro -[`for`]: ../expressions/loop-expr.md#iterator-loops -[`if let`]: ../expressions/if-expr.md#if-let-patterns -[`let`]: ../statements.md#let-statements -[`macro_rules` declarations]: ../macros-by-example.md -[`match`]: ../expressions/match-expr.md -[`Self` constructors]: ../paths.md#self-1 -[`Self` type]: ../paths.md#self-1 -[`use` import]: ../items/use-declarations.md -[`while let`]: ../expressions/loop-expr.md#while-let-patterns [Associated const declarations]: ../items/associated-items.md#associated-constants [Associated function declarations]: ../items/associated-items.md#associated-functions-and-methods [Associated type declarations]: ../items/associated-items.md#associated-types [Attribute macros]: ../procedural-macros.md#the-proc_macro_attribute-attribute -[attributes]: ../attributes.md -[bang-style macros]: ../macros.md [Block labels]: expr.loop.block-labels -[boolean]: ../types/boolean.md [Built-in attributes]: ../attributes.md#built-in-attributes-index -[closure parameters]: ../expressions/closure-expr.md -[closure]: ../expressions/closure-expr.md [Constant item declarations]: ../items/constant-items.md [Derive macro helpers]: ../procedural-macros.md#derive-macro-helper-attributes [Derive macros]: macro.proc.derive -[entity]: ../glossary.md#entity [Enum variant constructors]: ../items/enumerations.md -[enum]: ../items/enumerations.md [External crate declarations]: ../items/extern-crates.md [External crate prelude]: preludes.md#extern-prelude -[field expression]: ../expressions/field-expr.md [Function declarations]: ../items/functions.md -[function parameters]: ../items/functions.md#function-parameters [Function-like procedural macros]: ../procedural-macros.md#the-proc_macro-attribute [Generic const parameters]: ../items/generics.md#const-generics [Generic lifetime parameters]: ../items/generics.md [Generic type parameters]: ../items/generics.md [Loop labels]: ../expressions/loop-expr.md#loop-labels [Module declarations]: ../items/modules.md -[name resolution]: name-resolution.md -[names]: ../names.md -[numeric]: ../types/numeric.md [Static item declarations]: ../items/static-items.md [Struct constructors]: ../items/structs.md [Struct]: ../items/structs.md -[textual]: ../types/textual.md [Tool attribute modules]: ../attributes.md#tool-attributes [Tool attributes]: ../attributes.md#tool-attributes [Trait item declarations]: ../items/traits.md [Type aliases]: ../items/type-aliases.md +[`Self` constructors]: ../paths.md#self-1 +[`Self` type]: ../paths.md#self-1 +[`cfg` attribute]: ../conditional-compilation.md#the-cfg-attribute +[`cfg` macro]: ../conditional-compilation.md#the-cfg-macro +[`for`]: ../expressions/loop-expr.md#iterator-loops +[`if let`]: ../expressions/if-expr.md#if-let-patterns +[`let`]: ../statements.md#let-statements +[`macro_rules` declarations]: ../macros-by-example.md +[`match`]: ../expressions/match-expr.md +[`use` import]: ../items/use-declarations.md +[`while let`]: ../expressions/loop-expr.md#while-let-patterns +[attributes]: ../attributes.md +[bang-style macros]: ../macros.md +[boolean]: ../types/boolean.md +[closure parameters]: ../expressions/closure-expr.md +[closure]: ../expressions/closure-expr.md +[entity]: ../glossary.md#entity +[enum]: ../items/enumerations.md +[field expression]: ../expressions/field-expr.md +[function parameters]: ../items/functions.md#function-parameters +[name resolution ambiguity errors]: name-resolution.md#r-names.resolution.expansion.imports.ambiguity.pathvstextualmacro +[name resolution]: name-resolution.md +[names]: ../names.md +[numeric]: ../types/numeric.md +[textual]: ../types/textual.md [union]: ../items/unions.md [use declaration]: ../items/use-declarations.md + diff --git a/src/names/preludes.md b/src/names/preludes.md index 97c1ba77..3a2c3ff1 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -76,35 +76,46 @@ See https://github.com/rust-lang/rust/issues/57288 for more about the alloc/test limitation. --> + r[names.preludes.extern.no_std] ### The `no_std` attribute r[names.preludes.extern.no_std.intro] -By default, the standard library is automatically included in the crate root -module. The [`std`] crate is added to the root, along with an implicit -[`macro_use` attribute] pulling in all macros exported from `std` into the -[`macro_use` prelude]. Both [`core`] and [`std`] are added to the [extern -prelude]. +The *`no_std` [attribute][attributes]* causes the [`std`] crate to not be linked automatically, the [standard library prelude] to instead use the `core` prelude, and the [`macro_use` prelude] to instead use the macros exported from the `core` crate. + +> [!EXAMPLE] +> +> ```rust,ignore +> #![no_std] +> ``` + +> [!NOTE] +> Using `no_std` is useful when either the crate is targeting a platform that does not support the standard library or is purposefully not using the capabilities of the standard library. Those capabilities are mainly dynamic memory allocation (e.g. `Box` and `Vec`) and file and network capabilities (e.g. `std::fs` and `std::io`). + +> [!WARNING] +> Using `no_std` does not prevent the standard library from being linked. It is still valid to write `extern crate std` in the crate or in one of its dependencies; this will cause the compiler to link the `std` crate into the program. + +r[names.preludes.extern.no_std.syntax] +The `no_std` attribute uses the [MetaWord] syntax. r[names.preludes.extern.no_std.allowed-positions] -The *`no_std` [attribute]* may be applied at the crate level to prevent the -[`std`] crate from being automatically added into scope. +The `no_std` attribute may only be applied to the crate root. -It does three things: +r[names.preludes.extern.no_std.duplicates] +The `no_std` attribute may be used any number of times on a form. + +> [!NOTE] +> `rustc` lints against any use following the first. -r[names.preludes.extern.no_std.extern] -* Prevents `std` from being added to the [extern prelude](#extern-prelude). r[names.preludes.extern.no_std.module] -* Affects which module is used to make up the [standard library prelude] (as described above). -r[names.preludes.extern.no_std.core] -* Injects the [`core`] crate into the crate root instead of [`std`], and pulls - in all macros exported from `core` in the [`macro_use` prelude]. +The `no_std` attribute changes the [standard library prelude] to use the `core` prelude instead of the `std` prelude. -> [!NOTE] -> Using the core prelude over the standard prelude is useful when either the crate is targeting a platform that does not support the standard library or is purposefully not using the capabilities of the standard library. Those capabilities are mainly dynamic memory allocation (e.g. `Box` and `Vec`) and file and network capabilities (e.g. `std::fs` and `std::io`). +r[names.preludes.extern.no_std.macro_use] +By default, all macros exported from the `std` crate are added to the [`macro_use` prelude]. If the `no_std` attribute is specified, then all macros exported from the `core` crate are placed into the [`macro_use` prelude] instead. -> [!WARNING] -> Using `no_std` does not prevent the standard library from being linked in. It is still valid to put `extern crate std;` into the crate and dependencies can also link it in. +r[names.preludes.extern.no_std.edition2018] +> [!EDITION-2018] +> Before the 2018 edition, `std` is injected into the crate root by default. If `no_std` is specified, `core` is injected instead. Starting with the 2018 edition, regardless of `no_std` being specified, neither is injected into the crate root. r[names.preludes.lang] ## Language prelude @@ -140,27 +151,56 @@ r[names.preludes.tool.intro] The tool prelude includes tool names for external tools in the [type namespace]. See the [tool attributes] section for more details. + r[names.preludes.no_implicit_prelude] ## The `no_implicit_prelude` attribute r[names.preludes.no_implicit_prelude.intro] -The *`no_implicit_prelude` [attribute]* may be applied at the crate level or -on a module to indicate that it should not automatically bring the [standard -library prelude], [extern prelude], or [tool prelude] into scope for that -module or any of its descendants. +The *`no_implicit_prelude` [attribute]* is used to prevent implicit preludes from being brought into scope. + +> [!EXAMPLE] +> ```rust +> // The attribute can be applied to the crate root to affect +> // all modules. +> #![no_implicit_prelude] +> +> // Or it can be applied to a module to only affect that module +> // and its descendants. +> #[no_implicit_prelude] +> mod example { +> // ... +> } +> ``` + +r[names.preludes.no_implicit_prelude.syntax] +The `no_implicit_prelude` attribute uses the [MetaWord] syntax. + +r[names.preludes.no_implicit_prelude.allowed-positions] +The `no_implicit_prelude` attribute may only be applied to the crate or to a module. + +> [!NOTE] +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. + +r[names.preludes.no_implicit_prelude.duplicates] +The `no_implicit_prelude` attribute may be used any number of times on a form. + +> [!NOTE] +> `rustc` lints against any use following the first. + +r[names.preludes.no_implicit_prelude.excluded-preludes] +The `no_implicit_prelude` attribute prevents the [standard library prelude], [extern prelude], [`macro_use` prelude], and the [tool prelude] from being brought into scope for the module and its descendants. r[names.preludes.no_implicit_prelude.lang] -This attribute does not affect the [language prelude]. +The `no_implicit_prelude` attribute does not affect the [language prelude]. r[names.preludes.no_implicit_prelude.edition2018] > [!EDITION-2018] -> In the 2015 edition, the `no_implicit_prelude` attribute does not affect the [`macro_use` prelude], and all macros exported from the standard library are still included in the `macro_use` prelude. Starting in the 2018 edition, it will remove the `macro_use` prelude. +> In the 2015 edition, the `no_implicit_prelude` attribute does not affect the [`macro_use` prelude], and all macros exported from the standard library are still included in the `macro_use` prelude. Starting in the 2018 edition, the attribute does remove the `macro_use` prelude. [`extern crate`]: ../items/extern-crates.md [`macro_use` attribute]: ../macros-by-example.md#the-macro_use-attribute [`macro_use` prelude]: #macro_use-prelude [`no_std` attribute]: #the-no_std-attribute -[`no_std` attribute]: #the-no_std-attribute [attribute]: ../attributes.md [Boolean type]: ../types/boolean.md [Built-in attributes]: ../attributes.md#built-in-attributes-index @@ -171,7 +211,7 @@ r[names.preludes.no_implicit_prelude.edition2018] [Machine-dependent integer types]: ../types/numeric.md#machine-dependent-integer-types [Macro namespace]: namespaces.md [name resolution]: name-resolution.md -[Standard library prelude]: #standard-library-prelude +[standard library prelude]: names.preludes.std [Textual types]: ../types/textual.md [tool attributes]: ../attributes.md#tool-attributes [Tool prelude]: #tool-prelude diff --git a/src/procedural-macros.md b/src/procedural-macros.md index 4395e3db..721991f1 100644 --- a/src/procedural-macros.md +++ b/src/procedural-macros.md @@ -240,6 +240,24 @@ A helper attribute for a derive macro is declared by adding its identifier to th > } > ``` +r[macro.proc.derive.attributes.scope] +When a derive macro invocation is applied to an item, the helper attributes introduced by that derive macro become in scope 1) for attributes that are applied to that item and are applied lexically after the derive macro invocation and 2) for attributes that are applied to fields and variants inside of the item. + +> [!NOTE] +> rustc currently allows derive helpers to be used before the macro that introduces them. Such derive helpers used out of order may not shadow other attribute macros. This behavior is deprecated and slated for removal. +> +> +> ```rust,ignore +> #[helper] // Deprecated, hard error in the future. +> #[derive(WithHelperAttr)] +> struct Struct { +> field: (), +> } +> ``` +> +> For more details, see [Rust issue #79202](https://github.com/rust-lang/rust/issues/79202). + + r[macro.proc.attribute] ## The `proc_macro_attribute` attribute @@ -432,6 +450,7 @@ their equivalent `#[doc = r"str"]` attributes when passed to macros. [items]: items.md [macro namespace]: names/namespaces.md [module]: items/modules.md +[name resolution ambiguities]: names/name-resolution.md#r-names.resolution.expansion.imports.ambiguity.derivehelper [patterns]: patterns.md [public]: visibility-and-privacy.md [statements]: statements.md diff --git a/src/syntax-index.md b/src/syntax-index.md index 03df966d..b07b1867 100644 --- a/src/syntax-index.md +++ b/src/syntax-index.md @@ -76,9 +76,9 @@ This appendix provides an index of tokens and common forms with links to where t | `^` | Caret | [bitwise and logical XOR][arith] | | `!` | Not | [bitwise and logical NOT][negation], [macro calls], [inner attributes][attributes], [never type], [negative impls] | | `&` | And | [bitwise and logical AND][arith], [borrow], [references], [reference patterns] | -| \| | Or | [bitwise and logical OR][arith], [closures], [or patterns], [if let], [while let] | +| `\|` | Or | [bitwise and logical OR][arith], [closures], [or patterns], [if let], [while let] | | `&&` | AndAnd | [lazy AND][lazy-bool], [borrow], [references], [reference patterns] | -| \|\| | OrOr | [lazy OR][lazy-bool], [closures] | +| `\|\|` | OrOr | [lazy OR][lazy-bool], [closures] | | `<<` | Shl | [shift left][arith], [nested generics][generics] | | `>>` | Shr | [shift right][arith], [nested generics][generics] | | `+=` | PlusEq | [addition assignment][compound] | @@ -88,7 +88,7 @@ This appendix provides an index of tokens and common forms with links to where t | `%=` | PercentEq | [remainder assignment][compound] | | `^=` | CaretEq | [bitwise XOR assignment][compound] | | `&=` | AndEq | [bitwise AND assignment][compound] | -| \|= | OrEq | [bitwise OR assignment][compound] | +| `\|=` | OrEq | [bitwise OR assignment][compound] | | `<<=` | ShlEq | [shift left assignment][compound] | | `>>=` | ShrEq | [shift right assignment][compound], [nested generics][generics] | | `=` | Eq | [assignment], [let statements], [attributes], various type definitions | @@ -164,7 +164,7 @@ This appendix provides an index of tokens and common forms with links to where t | Expression | Use | |---------------------------|-----| -| \|…\| expr
\|…\| -> Type { … } | [closures] | +| `\|…\| expr`
`\|…\| -> Type { … }` | [closures] | | `ident::…` | [paths] | | `::crate_name::…` | [explicit crate paths] | | `crate::…` | [crate-relative paths] | @@ -301,7 +301,6 @@ This appendix provides an index of tokens and common forms with links to where t [closure expressions]: expr.closure [closures]: expr.closure [comparison]: expr.cmp -[compound type bounds]: bound [compound]: expr.compound-assign [configuration predicates]: cfg [const assembly operands]: asm.operand-type.supported-operands.const @@ -321,7 +320,6 @@ This appendix provides an index of tokens and common forms with links to where t [extern crate]: items.extern-crate [extern function pointer types]: type.fn-pointer.qualifiers [extern function qualifier]: items.fn.extern -[extern]: items.extern [external block functions]: items.extern.fn [external block statics]: items.extern.static [external blocks]: items.extern @@ -349,7 +347,6 @@ This appendix provides an index of tokens and common forms with links to where t [inherent impls]: items.impl.inherent [inner attribute]: attributes.inner [iterator loops]: expr.loop.for -[keywords chapter]: lex.keywords [lazy-bool]: expr.bool-logic [let statements]: statement.let [lifetime bounds]: bound.lifetime @@ -407,7 +404,6 @@ This appendix provides an index of tokens and common forms with links to where t [return expressions]: expr.return [self parameters]: items.fn.params.self-pat [single-element tuple expressions]: expr.tuple -[sized]: bound.sized [slice patterns]: patterns.slice [slice types]: type.slice [static items]: items.static diff --git a/src/types/boolean.md b/src/types/boolean.md index fdb306eb..27ec97cb 100644 --- a/src/types/boolean.md +++ b/src/types/boolean.md @@ -61,7 +61,7 @@ r[type.bool.expr.not] r[type.bool.expr.or] ### Logical or -| `a` | `b` | [a | b][op-or] | +| `a` | `b` | [`a \| b`][op-or] | |- | - | - | | `true` | `true` | `true` | | `true` | `false` | `true` | diff --git a/src/types/numeric.md b/src/types/numeric.md index 73c61991..5b796e41 100644 --- a/src/types/numeric.md +++ b/src/types/numeric.md @@ -44,7 +44,7 @@ platform's pointer type. It can represent every memory address in the process. > For more information, see the documentation for [type cast expressions], [`std::ptr`], and [provenance][std::ptr#provenance] in particular. r[type.numeric.int.size.isize] -The `isize` type is a signed integer type with the same number of bits as the +The `isize` type is a signed two's complement integer type with the same number of bits as the platform's pointer type. The theoretical upper bound on object and array size is the maximum `isize` value. This ensures that `isize` can be used to calculate differences between pointers into an object or array and can address every byte diff --git a/theme/reference.css b/theme/reference.css index eb1760d6..7b486671 100644 --- a/theme/reference.css +++ b/theme/reference.css @@ -261,7 +261,7 @@ dfn { padding-right: 0; } /* required to accommodate above, somehow... */ -#menu-bar { +#mdbook-menu-bar { margin-left: 0; }