diff --git a/.gitignore b/.gitignore
index 487867c375d45..81a472451d777 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,6 @@
-# This file should only ignore things that are generated during a `x.py` build,
-# generated by common IDEs, and optional files controlled by the user that
-# affect the build (such as config.toml).
-# In particular, things like `mir_dump` should not be listed here; they are only
-# created during manual debugging and many people like to clean up instead of
-# having git ignore such leftovers. You can use `.git/info/exclude` to
-# configure your local ignore list.
+# This file should only ignore things that are generated during a build,
+# generated by common IDEs, and optional files controlled by the user
+# that affect the build (such as config.toml).
# FIXME: This needs cleanup.
*~
.#*
@@ -56,4 +52,3 @@ config.stamp
Session.vim
.cargo
no_llvm_build
-# Before adding new lines, see the comment at the top.
diff --git a/.gitmodules b/.gitmodules
index 1dcf9ed319f14..3ff5af78097fa 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -28,6 +28,9 @@
[submodule "src/doc/rust-by-example"]
path = src/doc/rust-by-example
url = https://github.com/rust-lang/rust-by-example.git
+[submodule "src/llvm-emscripten"]
+ path = src/llvm-emscripten
+ url = https://github.com/rust-lang/llvm.git
[submodule "src/stdarch"]
path = src/stdarch
url = https://github.com/rust-lang/stdarch.git
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index e3708bc485399..ece8dedb0aed7 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -1,3 +1,40 @@
# The Rust Code of Conduct
-The Code of Conduct for this repository [can be found online](https://www.rust-lang.org/conduct.html).
+A version of this document [can be found online](https://www.rust-lang.org/conduct.html).
+
+## Conduct
+
+**Contact**: [rust-mods@rust-lang.org](mailto:rust-mods@rust-lang.org)
+
+* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic.
+* On IRC, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all.
+* Please be kind and courteous. There's no need to be mean or rude.
+* Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer.
+* Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works.
+* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the Citizen Code of Conduct; if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups.
+* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [Rust moderation team][mod_team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back.
+* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome.
+
+## Moderation
+
+
+These are the policies for upholding our community's standards of conduct. If you feel that a thread needs moderation, please contact the [Rust moderation team][mod_team].
+
+1. Remarks that violate the Rust standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.)
+2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed.
+3. Moderators will first respond to such remarks with a warning.
+4. If the warning is unheeded, the user will be "kicked," i.e., kicked out of the communication channel to cool off.
+5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded.
+6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology.
+7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, **in private**. Complaints about bans in-channel are not allowed.
+8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others.
+
+In the Rust community we strive to go the extra step to look out for each other. Don't just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they're off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely.
+
+And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could've communicated better — remember that it's your responsibility to make your fellow Rustaceans comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust.
+
+The enforcement policies listed above apply to all official Rust venues; including official IRC channels (#rust, #rust-internals, #rust-tools, #rust-libs, #rustc, #rust-beginners, #rust-docs, #rust-community, #rust-lang, and #cargo); GitHub repositories under rust-lang, rust-lang-nursery, and rust-lang-deprecated; and all forums under rust-lang.org (users.rust-lang.org, internals.rust-lang.org). For other projects adopting the Rust Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion.
+
+*Adapted from the [Node.js Policy on Trolling](https://blog.izs.me/2012/08/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).*
+
+[mod_team]: https://www.rust-lang.org/team.html#Moderation-team
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 37a217d2a0452..4daaa986a2dc2 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -15,7 +15,7 @@ links to the major sections:
* [Helpful Links and Information](#helpful-links-and-information)
If you have questions, please make a post on [internals.rust-lang.org][internals] or
-hop on the [Rust Discord server][rust-discord] or [Rust Zulip server][rust-zulip].
+hop on the [Rust Discord server][rust-discord], [Rust Zulip server][rust-zulip] or [#rust-internals][pound-rust-internals].
As a reminder, all contributors are expected to follow our [Code of Conduct][coc].
@@ -25,6 +25,7 @@ to contribute to it in more detail than this document.
If this is your first time contributing, the [walkthrough] chapter of the guide
can give you a good example of how a typical contribution would go.
+[pound-rust-internals]: https://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-internals
[internals]: https://internals.rust-lang.org
[rust-discord]: http://discord.gg/rust-lang
[rust-zulip]: https://rust-lang.zulipchat.com
@@ -128,14 +129,6 @@ the master branch to your feature branch.
Also, please make sure that fixup commits are squashed into other related
commits with meaningful commit messages.
-GitHub allows [closing issues using keywords][closing-keywords]. This feature
-should be used to keep the issue tracker tidy. However, it is generally preferred
-to put the "closes #123" text in the PR description rather than the issue commit;
-particularly during rebasing, citing the issue number in the commit can "spam"
-the issue in question.
-
-[closing-keywords]: https://help.github.com/en/articles/closing-issues-using-keywords
-
Please make sure your pull request is in compliance with Rust's style
guidelines by running
@@ -411,7 +404,7 @@ If you're looking for somewhere to start, check out the [E-easy][eeasy] tag.
There are a number of other ways to contribute to Rust that don't deal with
this repository.
-Answer questions in the _Get Help!_ channels from the [Rust Discord server][rust-discord], on [users.rust-lang.org][users],
+Answer questions in [#rust][pound-rust], or on [users.rust-lang.org][users],
or on [StackOverflow][so].
Participate in the [RFC process](https://github.com/rust-lang/rfcs).
@@ -420,7 +413,7 @@ Find a [requested community library][community-library], build it, and publish
it to [Crates.io](http://crates.io). Easier said than done, but very, very
valuable!
-[rust-discord]: https://discord.gg/rust-lang
+[pound-rust]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust
[users]: https://users.rust-lang.org/
[so]: http://stackoverflow.com/questions/tagged/rust
[community-library]: https://github.com/rust-lang/rfcs/labels/A-community-library
diff --git a/Cargo.lock b/Cargo.lock
index fbac2c7879d12..5a92011d57033 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -107,12 +107,6 @@ dependencies = [
"winapi 0.3.6",
]
-[[package]]
-name = "autocfg"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875"
-
[[package]]
name = "backtrace"
version = "0.3.37"
@@ -271,7 +265,7 @@ dependencies = [
[[package]]
name = "cargo"
-version = "0.41.0"
+version = "0.40.0"
dependencies = [
"atty",
"bytesize",
@@ -373,18 +367,6 @@ dependencies = [
"serde_json",
]
-[[package]]
-name = "cargo_metadata"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d2d1617e838936c0d2323a65cc151e03ae19a7678dd24f72bccf27119b90a5d"
-dependencies = [
- "semver",
- "serde",
- "serde_derive",
- "serde_json",
-]
-
[[package]]
name = "cargotest2"
version = "0.1.0"
@@ -455,7 +437,7 @@ dependencies = [
name = "clippy"
version = "0.0.212"
dependencies = [
- "cargo_metadata 0.9.0",
+ "cargo_metadata",
"clippy-mini-macro-test",
"clippy_lints",
"compiletest_rs",
@@ -476,7 +458,7 @@ version = "0.2.0"
name = "clippy_lints"
version = "0.0.212"
dependencies = [
- "cargo_metadata 0.9.0",
+ "cargo_metadata",
"if_chain",
"itertools 0.8.0",
"lazy_static 1.3.0",
@@ -568,9 +550,9 @@ dependencies = [
[[package]]
name = "compiletest_rs"
-version = "0.3.25"
+version = "0.3.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f75b10a18fb53549fdd090846eb01c7f8593914494d1faabc4d3005c436e417a"
+checksum = "eb783fe7afb90ec3d3e49ccaf9196d29ab63c6ed61d4b0695839daa580ae3a3d"
dependencies = [
"diff",
"filetime",
@@ -584,6 +566,7 @@ dependencies = [
"serde_derive",
"serde_json",
"tempfile",
+ "tester",
"winapi 0.3.6",
]
@@ -618,7 +601,7 @@ checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
[[package]]
name = "crates-io"
-version = "0.29.0"
+version = "0.28.0"
dependencies = [
"curl",
"failure",
@@ -677,16 +660,6 @@ dependencies = [
"crossbeam-utils 0.6.5",
]
-[[package]]
-name = "crossbeam-deque"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71"
-dependencies = [
- "crossbeam-epoch 0.7.2",
- "crossbeam-utils 0.6.5",
-]
-
[[package]]
name = "crossbeam-epoch"
version = "0.3.1"
@@ -758,24 +731,25 @@ dependencies = [
[[package]]
name = "curl"
-version = "0.4.24"
+version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d08ad3cb89d076a36b0ce5749eec2c9964f70c0c58480ab6b75a91ec4fc206d8"
+checksum = "a85f2f95f2bd277d316d1aa8a477687ab4a6942258c7db7c89c187534669979c"
dependencies = [
"curl-sys",
+ "kernel32-sys",
"libc",
"openssl-probe",
"openssl-sys",
"schannel",
"socket2",
- "winapi 0.3.6",
+ "winapi 0.2.8",
]
[[package]]
name = "curl-sys"
-version = "0.4.22"
+version = "0.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e9a9a4e417722876332136a00cacf92c2ceb331fab4b52b6a1ad16c6cd79255"
+checksum = "9d91a0052d5b982887d8e829bee0faffc7218ea3c6ebd3d6c2c8f678a93c9a42"
dependencies = [
"cc",
"libc",
@@ -1021,7 +995,7 @@ dependencies = [
"proc-macro2 0.4.30",
"quote 0.6.12",
"syn 0.15.35",
- "synstructure 0.10.2",
+ "synstructure",
]
[[package]]
@@ -1287,7 +1261,7 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df044dd42cdb7e32f28557b661406fc0f2494be75199779998810dbc35030e0d"
dependencies = [
- "hashbrown 0.5.0",
+ "hashbrown",
"lazy_static 1.3.0",
"log",
"pest",
@@ -1304,19 +1278,10 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1de41fb8dba9714efd92241565cdff73f78508c95697dd56787d3cba27e2353"
dependencies = [
- "serde",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3cd9867f119b19fecb08cd5c326ad4488d7a1da4bf75b4d95d71db742525aaab"
-dependencies = [
- "autocfg",
"compiler_builtins",
"rustc-std-workspace-alloc",
"rustc-std-workspace-core",
+ "serde",
]
[[package]]
@@ -1342,9 +1307,9 @@ checksum = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e"
[[package]]
name = "home"
-version = "0.5.1"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3753954f7bd71f0e671afb8b5a992d1724cf43b7f95a563cd4a0bde94659ca8"
+checksum = "c07c315e106bd6f83f026a20ddaeef2706782e490db1dcdd37caad38a0e895b3"
dependencies = [
"scopeguard 1.0.0",
"winapi 0.3.6",
@@ -1725,9 +1690,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
[[package]]
name = "libc"
-version = "0.2.64"
+version = "0.2.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74dfca3d9957906e8d1e6a0b641dc9a59848e793f1da2165889fd4f62d10d79c"
+checksum = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
dependencies = [
"rustc-std-workspace-core",
]
@@ -2136,7 +2101,7 @@ name = "miri"
version = "0.1.0"
dependencies = [
"byteorder",
- "cargo_metadata 0.8.0",
+ "cargo_metadata",
"colored",
"compiletest_rs",
"directories",
@@ -2669,9 +2634,9 @@ dependencies = [
[[package]]
name = "racer"
-version = "2.1.28"
+version = "2.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acc70369054bad4ad0c16a3f45cd73e0695361a3af35c7b465e619ac2674f064"
+checksum = "dde22b84ab75220015cbd91240222402bf885cbe3a5dc856475771abb82533ae"
dependencies = [
"bitflags",
"clap",
@@ -2828,22 +2793,22 @@ dependencies = [
[[package]]
name = "rayon"
-version = "1.2.0"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83a27732a533a1be0a0035a111fe76db89ad312f6f0347004c220c57f209a123"
+checksum = "a4b0186e22767d5b9738a05eab7c6ac90b15db17e5b5f9bd87976dd7d89a10a4"
dependencies = [
- "crossbeam-deque 0.7.1",
+ "crossbeam-deque 0.6.3",
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
-version = "1.6.0"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98dcf634205083b17d0861252431eb2acbfb698ab7478a2d20de07954f47ec7b"
+checksum = "ebbe0df8435ac0c397d467b6cad6d25543d06e8a019ef3f6af3c384597515bd2"
dependencies = [
- "crossbeam-deque 0.7.1",
+ "crossbeam-deque 0.6.3",
"crossbeam-queue",
"crossbeam-utils 0.6.5",
"lazy_static 1.3.0",
@@ -2966,7 +2931,7 @@ name = "rls"
version = "1.39.0"
dependencies = [
"cargo",
- "cargo_metadata 0.8.0",
+ "cargo_metadata",
"clippy_lints",
"crossbeam-channel",
"difference",
@@ -3111,28 +3076,26 @@ dependencies = [
"num_cpus",
"parking_lot 0.9.0",
"polonius-engine",
- "rustc-rayon 0.3.0",
- "rustc-rayon-core 0.3.0",
+ "rustc-rayon",
+ "rustc-rayon-core",
"rustc_apfloat",
"rustc_data_structures",
"rustc_errors",
"rustc_fs_util",
- "rustc_index",
"rustc_macros",
"rustc_target",
"scoped-tls",
"serialize",
"smallvec",
"syntax",
- "syntax_expand",
"syntax_pos",
]
[[package]]
name = "rustc-ap-arena"
-version = "606.0.0"
+version = "583.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a623fd4805842e9bd0bb6e6dace63efede0ee22de4522a0b03b7c3d15a22f009"
+checksum = "f59b76d334bd533f3fdc5c651c27678c5e80fac67c6f7da22ba21a58878c55f5"
dependencies = [
"rustc-ap-rustc_data_structures",
"smallvec",
@@ -3140,15 +3103,15 @@ dependencies = [
[[package]]
name = "rustc-ap-graphviz"
-version = "606.0.0"
+version = "583.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee549ade784b444ef10c0240c3487ed785aa65d711071f7984246b15329a17b6"
+checksum = "3e632ef08ca17458acfd46d2ead3d541a1c249586cd5329f5fe333dacfab6142"
[[package]]
name = "rustc-ap-rustc_data_structures"
-version = "606.0.0"
+version = "583.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca545744a5a9b42e3d0410d6290d40de96dd567253fe77f310c1de4afd213dd4"
+checksum = "e89e2c7be68185418f3cd56af3df8b29007a59a1cebefa63612d055f9bcb1a36"
dependencies = [
"cfg-if",
"crossbeam-utils 0.6.5",
@@ -3157,22 +3120,21 @@ dependencies = [
"jobserver",
"lazy_static 1.3.0",
"log",
- "parking_lot 0.9.0",
+ "parking_lot 0.7.1",
"rustc-ap-graphviz",
- "rustc-ap-rustc_index",
"rustc-ap-serialize",
"rustc-hash",
- "rustc-rayon 0.2.0",
- "rustc-rayon-core 0.2.0",
+ "rustc-rayon",
+ "rustc-rayon-core",
"smallvec",
"stable_deref_trait",
]
[[package]]
name = "rustc-ap-rustc_errors"
-version = "606.0.0"
+version = "583.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6967a41ed38ef4bce0f559fe9a4801d8ba12ac032f40a12a55e72f79d52c9bb"
+checksum = "1e47cb380abeb72b01e42b2342d592f7eeea7d536c2f1f0d0e550dc509e46333"
dependencies = [
"annotate-snippets",
"atty",
@@ -3185,57 +3147,46 @@ dependencies = [
"unicode-width",
]
-[[package]]
-name = "rustc-ap-rustc_index"
-version = "606.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "457a5c204ae2fdaa5bdb5b196e58ca59896870d80445fe423063c9453496e3ea"
-dependencies = [
- "rustc-ap-serialize",
- "smallvec",
-]
-
[[package]]
name = "rustc-ap-rustc_lexer"
-version = "606.0.0"
+version = "583.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed0c064676f8a08e42a36b0d4e4a102465fb0f4b75e11436cb7f66d2c3fa7139"
+checksum = "494cfaf67f49217d67d0774eeecbba61ac89acf478db97ef11f113ed8a959305"
dependencies = [
"unicode-xid 0.2.0",
]
[[package]]
name = "rustc-ap-rustc_macros"
-version = "606.0.0"
+version = "583.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2d77e46159c5288c585decbcdc9d742889c65e307c31e104c7a36d63fe1f5d0"
+checksum = "e2e5d36becc59b4497f9cbd3ae0610081de0207a1d0e95c066369167b14f486f"
dependencies = [
"itertools 0.8.0",
"proc-macro2 0.4.30",
"quote 0.6.12",
"syn 0.15.35",
- "synstructure 0.10.2",
+ "synstructure",
]
[[package]]
name = "rustc-ap-rustc_target"
-version = "606.0.0"
+version = "583.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86ca895350b0de14d064b499168c93fa183958d5462eb042c927d93623e41ec1"
+checksum = "a7bfc5f96dfc3b9f8d5b57884f7f37467ecff6776cd4b8b491a7daece6fdd7c2"
dependencies = [
"bitflags",
"log",
"rustc-ap-rustc_data_structures",
- "rustc-ap-rustc_index",
"rustc-ap-serialize",
"rustc-ap-syntax_pos",
]
[[package]]
name = "rustc-ap-serialize"
-version = "606.0.0"
+version = "583.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92679240e86f4583cc05f8dcf6439bdab87bac9e6555718469176de9bd52ba20"
+checksum = "2bb9ee231cf79eded39c56647499f83d6136ff5c8c0baaa9e21b6febee00f4f6"
dependencies = [
"indexmap",
"smallvec",
@@ -3243,17 +3194,17 @@ dependencies = [
[[package]]
name = "rustc-ap-syntax"
-version = "606.0.0"
+version = "583.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a0c30f8e38c847dbfd9e2f1e472ab06d0bd0a23ab53ae4c5a44912842ce834e"
+checksum = "b3827fc208814efbde82d613e31d11b4250ce9e8cf8afe4a4d47bbbd099632c9"
dependencies = [
"bitflags",
"lazy_static 1.3.0",
"log",
"rustc-ap-rustc_data_structures",
"rustc-ap-rustc_errors",
- "rustc-ap-rustc_index",
"rustc-ap-rustc_lexer",
+ "rustc-ap-rustc_macros",
"rustc-ap-rustc_target",
"rustc-ap-serialize",
"rustc-ap-syntax_pos",
@@ -3263,14 +3214,13 @@ dependencies = [
[[package]]
name = "rustc-ap-syntax_pos"
-version = "606.0.0"
+version = "583.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bdaa0fb40143b4b878256ac4e2b498885daafc269502504d91929eab4744bf4"
+checksum = "930ed81c34f325e512cc315c04d676fa84a373879d5c43bb54054a0522b05213"
dependencies = [
"cfg-if",
"rustc-ap-arena",
"rustc-ap-rustc_data_structures",
- "rustc-ap-rustc_index",
"rustc-ap-rustc_macros",
"rustc-ap-serialize",
"scoped-tls",
@@ -3314,18 +3264,7 @@ checksum = "0d2e07e19601f21c59aad953c2632172ba70cb27e685771514ea66e4062b3363"
dependencies = [
"crossbeam-deque 0.2.0",
"either",
- "rustc-rayon-core 0.2.0",
-]
-
-[[package]]
-name = "rustc-rayon"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f32767f90d938f1b7199a174ef249ae1924f6e5bbdb9d112fea141e016f25b3a"
-dependencies = [
- "crossbeam-deque 0.7.1",
- "either",
- "rustc-rayon-core 0.3.0",
+ "rustc-rayon-core",
]
[[package]]
@@ -3340,19 +3279,6 @@ dependencies = [
"num_cpus",
]
-[[package]]
-name = "rustc-rayon-core"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea2427831f0053ea3ea73559c8eabd893133a51b251d142bacee53c62a288cb3"
-dependencies = [
- "crossbeam-deque 0.7.1",
- "crossbeam-queue",
- "crossbeam-utils 0.6.5",
- "lazy_static 1.3.0",
- "num_cpus",
-]
-
[[package]]
name = "rustc-serialize"
version = "0.3.24"
@@ -3436,11 +3362,9 @@ dependencies = [
"rustc_errors",
"rustc_fs_util",
"rustc_incremental",
- "rustc_index",
"rustc_target",
"serialize",
"syntax",
- "syntax_expand",
"syntax_pos",
"tempfile",
]
@@ -3474,9 +3398,8 @@ dependencies = [
"log",
"parking_lot 0.9.0",
"rustc-hash",
- "rustc-rayon 0.3.0",
- "rustc-rayon-core 0.3.0",
- "rustc_index",
+ "rustc-rayon",
+ "rustc-rayon-core",
"serialize",
"smallvec",
"stable_deref_trait",
@@ -3495,7 +3418,6 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_interface",
- "rustc_lint",
"rustc_metadata",
"rustc_mir",
"rustc_plugin",
@@ -3541,14 +3463,6 @@ dependencies = [
"syntax_pos",
]
-[[package]]
-name = "rustc_index"
-version = "0.0.0"
-dependencies = [
- "serialize",
- "smallvec",
-]
-
[[package]]
name = "rustc_interface"
version = "0.0.0"
@@ -3556,7 +3470,7 @@ dependencies = [
"log",
"once_cell",
"rustc",
- "rustc-rayon 0.3.0",
+ "rustc-rayon",
"rustc_codegen_ssa",
"rustc_codegen_utils",
"rustc_data_structures",
@@ -3569,13 +3483,11 @@ dependencies = [
"rustc_plugin_impl",
"rustc_privacy",
"rustc_resolve",
- "rustc_target",
"rustc_traits",
"rustc_typeck",
"serialize",
"smallvec",
"syntax",
- "syntax_expand",
"syntax_ext",
"syntax_pos",
"tempfile",
@@ -3595,7 +3507,6 @@ dependencies = [
"log",
"rustc",
"rustc_data_structures",
- "rustc_index",
"rustc_target",
"syntax",
"syntax_pos",
@@ -3625,10 +3536,10 @@ name = "rustc_macros"
version = "0.1.0"
dependencies = [
"itertools 0.8.0",
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.5",
- "synstructure 0.12.1",
+ "proc-macro2 0.4.30",
+ "quote 0.6.12",
+ "syn 0.15.35",
+ "synstructure",
]
[[package]]
@@ -3641,13 +3552,11 @@ dependencies = [
"rustc",
"rustc_data_structures",
"rustc_errors",
- "rustc_index",
"rustc_target",
"serialize",
"smallvec",
"stable_deref_trait",
"syntax",
- "syntax_expand",
"syntax_pos",
]
@@ -3665,7 +3574,6 @@ dependencies = [
"rustc_apfloat",
"rustc_data_structures",
"rustc_errors",
- "rustc_index",
"rustc_lexer",
"rustc_target",
"serialize",
@@ -3693,10 +3601,7 @@ dependencies = [
"rustc",
"rustc_data_structures",
"rustc_errors",
- "rustc_index",
- "rustc_target",
"syntax",
- "syntax_expand",
"syntax_pos",
]
@@ -3714,7 +3619,6 @@ dependencies = [
"rustc",
"rustc_metadata",
"syntax",
- "syntax_expand",
"syntax_pos",
]
@@ -3743,7 +3647,6 @@ dependencies = [
"rustc_metadata",
"smallvec",
"syntax",
- "syntax_expand",
"syntax_pos",
]
@@ -3770,7 +3673,6 @@ dependencies = [
"bitflags",
"log",
"rustc_data_structures",
- "rustc_index",
"serialize",
"syntax_pos",
]
@@ -3819,7 +3721,6 @@ dependencies = [
"rustc",
"rustc_data_structures",
"rustc_errors",
- "rustc_index",
"rustc_target",
"smallvec",
"syntax",
@@ -3841,7 +3742,7 @@ version = "0.0.0"
dependencies = [
"minifier",
"pulldown-cmark 0.5.3",
- "rustc-rayon 0.3.0",
+ "rustc-rayon",
"tempfile",
]
@@ -3880,11 +3781,11 @@ dependencies = [
[[package]]
name = "rustfmt-nightly"
-version = "1.4.9"
+version = "1.4.8"
dependencies = [
"annotate-snippets",
"bytecount",
- "cargo_metadata 0.8.0",
+ "cargo_metadata",
"derive-new",
"diff",
"dirs",
@@ -4158,7 +4059,7 @@ dependencies = [
"core",
"dlmalloc",
"fortanix-sgx-abi",
- "hashbrown 0.6.2",
+ "hashbrown",
"libc",
"panic_abort",
"panic_unwind",
@@ -4327,18 +4228,6 @@ dependencies = [
"unicode-xid 0.1.0",
]
-[[package]]
-name = "synstructure"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f085a5855930c0441ca1288cf044ea4aecf4f43a91668abdb870b4ba546a203"
-dependencies = [
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.5",
- "unicode-xid 0.2.0",
-]
-
[[package]]
name = "syntax"
version = "0.0.0"
@@ -4348,31 +4237,11 @@ dependencies = [
"log",
"rustc_data_structures",
"rustc_errors",
- "rustc_index",
- "rustc_lexer",
- "rustc_target",
- "scoped-tls",
- "serialize",
- "smallvec",
- "syntax_pos",
-]
-
-[[package]]
-name = "syntax_expand"
-version = "0.0.0"
-dependencies = [
- "bitflags",
- "lazy_static 1.3.0",
- "log",
- "rustc_data_structures",
- "rustc_errors",
- "rustc_index",
"rustc_lexer",
"rustc_target",
"scoped-tls",
"serialize",
"smallvec",
- "syntax",
"syntax_pos",
]
@@ -4387,7 +4256,6 @@ dependencies = [
"rustc_target",
"smallvec",
"syntax",
- "syntax_expand",
"syntax_pos",
]
@@ -4398,7 +4266,6 @@ dependencies = [
"arena",
"cfg-if",
"rustc_data_structures",
- "rustc_index",
"rustc_macros",
"scoped-tls",
"serialize",
@@ -4456,6 +4323,16 @@ dependencies = [
"std",
]
+[[package]]
+name = "term"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
+dependencies = [
+ "kernel32-sys",
+ "winapi 0.2.8",
+]
+
[[package]]
name = "term"
version = "0.6.0"
@@ -4512,6 +4389,17 @@ dependencies = [
"term 0.0.0",
]
+[[package]]
+name = "tester"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e812cb26c597f86a49b26dbb58b878bd2a2b4b93fc069dc39499228fe556ff6"
+dependencies = [
+ "getopts",
+ "libc",
+ "term 0.4.6",
+]
+
[[package]]
name = "textwrap"
version = "0.11.0"
diff --git a/README.md b/README.md
index c5468a2924888..96d7e938be2f2 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,6 @@ or reading the [rustc guide][rustcguidebuild].
* `curl`
* `git`
* `ssl` which comes in `libssl-dev` or `openssl-devel`
- * `pkg-config` if you are compiling on Linux and targeting Linux
2. Clone the [source] with `git`:
@@ -244,17 +243,19 @@ The Rust community congregates in a few places:
To contribute to Rust, please see [CONTRIBUTING](CONTRIBUTING.md).
-Most real-time collaboration happens in a variety of channels on the
-[Rust Discord server][rust-discord], with channels dedicated for getting help,
-community, documentation, and all major contribution areas in the Rust ecosystem.
-A good place to ask for help would be the #help channel.
+Rust has an [IRC] culture and most real-time collaboration happens in a
+variety of channels on Mozilla's IRC network, irc.mozilla.org. The
+most popular channel is [#rust], a venue for general discussion about
+Rust. And a good place to ask for help would be [#rust-beginners].
The [rustc guide] might be a good place to start if you want to find out how
various parts of the compiler work.
Also, you may find the [rustdocs for the compiler itself][rustdocs] useful.
-[rust-discord]: https://discord.gg/rust-lang
+[IRC]: https://en.wikipedia.org/wiki/Internet_Relay_Chat
+[#rust]: irc://irc.mozilla.org/rust
+[#rust-beginners]: irc://irc.mozilla.org/rust-beginners
[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html
[rustdocs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/
diff --git a/config.toml.example b/config.toml.example
index e832570ed982e..848147c2974c1 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -258,9 +258,10 @@
[rust]
# Whether or not to optimize the compiler and standard library.
-# WARNING: Building with optimize = false is NOT SUPPORTED. Due to bootstrapping,
-# building without optimizations takes much longer than optimizing. Further, some platforms
-# fail to build without this optimization (c.f. #65352).
+#
+# Note: the slowness of the non optimized compiler compiling itself usually
+# outweighs the time gains in not doing optimizations, therefore a
+# full bootstrap takes much more time with `optimize` set to false.
#optimize = true
# Indicates that the build should be configured for debugging Rust. A
@@ -340,9 +341,6 @@
# nightly features
#channel = "dev"
-# The root location of the MUSL installation directory.
-#musl-root = "..."
-
# By default the `rustc` executable is built with `-Wl,-rpath` flags on Unix
# platforms to ensure that the compiler is usable by default from the build
# directory (as it links to a number of dynamic libraries). This may not be
@@ -376,7 +374,9 @@
# This is an array of the codegen backends that will be compiled for the rustc
# that's being compiled. The default is to only build the LLVM codegen backend,
-# and currently the only standard option supported is `"llvm"`
+# but you can also optionally enable the "emscripten" backend for asm.js or
+# make this an empty array (but that probably won't get too far in the
+# bootstrap)
#codegen-backends = ["llvm"]
# This is the name of the directory in which codegen backends will get installed
diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md
index c501378bff549..3e877fc4e317c 100644
--- a/src/bootstrap/README.md
+++ b/src/bootstrap/README.md
@@ -328,8 +328,6 @@ are:
`Config` struct.
* Adding a sanity check? Take a look at `bootstrap/sanity.rs`.
-If you have any questions feel free to reach out on `#infra` channel in the
-[Rust Discord server][rust-discord] or ask on internals.rust-lang.org. When
-you encounter bugs, please file issues on the rust-lang/rust issue tracker.
-
-[rust-discord]: https://discord.gg/rust-lang
+If you have any questions feel free to reach out on `#rust-infra` on IRC or ask on
+internals.rust-lang.org. When you encounter bugs, please file issues on the
+rust-lang/rust issue tracker.
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 4caf36a6f2a51..65129eeeec504 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -734,6 +734,10 @@ def update_submodules(self):
if module.endswith("llvm-project"):
if self.get_toml('llvm-config') and self.get_toml('lld') != 'true':
continue
+ if module.endswith("llvm-emscripten"):
+ backends = self.get_toml('codegen-backends')
+ if backends is None or not 'emscripten' in backends:
+ continue
check = self.check_submodule(module, slow_submodules)
filtered_submodules.append((module, check))
submodules_names.append(module)
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 2748903f2d475..5d586f0c461db 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -443,7 +443,6 @@ impl<'a> Builder<'a> {
dist::Rustc,
dist::DebuggerScripts,
dist::Std,
- dist::RustcDev,
dist::Analysis,
dist::Src,
dist::PlainSourceTarball,
@@ -818,22 +817,12 @@ impl<'a> Builder<'a> {
let mut rustflags = Rustflags::new(&target);
if stage != 0 {
- if let Ok(s) = env::var("CARGOFLAGS_NOT_BOOTSTRAP") {
- cargo.args(s.split_whitespace());
- }
rustflags.env("RUSTFLAGS_NOT_BOOTSTRAP");
} else {
- if let Ok(s) = env::var("CARGOFLAGS_BOOTSTRAP") {
- cargo.args(s.split_whitespace());
- }
rustflags.env("RUSTFLAGS_BOOTSTRAP");
rustflags.arg("--cfg=bootstrap");
}
- if let Ok(s) = env::var("CARGOFLAGS") {
- cargo.args(s.split_whitespace());
- }
-
match mode {
Mode::Std | Mode::ToolBootstrap | Mode::ToolStd => {},
Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {
@@ -981,7 +970,6 @@ impl<'a> Builder<'a> {
Some("-Wl,-rpath,@loader_path/../lib")
} else if !target.contains("windows") &&
!target.contains("wasm32") &&
- !target.contains("emscripten") &&
!target.contains("fuchsia") {
Some("-Wl,-rpath,$ORIGIN/../lib")
} else {
diff --git a/src/bootstrap/cache.rs b/src/bootstrap/cache.rs
index 4310f2c6fa140..53071df855297 100644
--- a/src/bootstrap/cache.rs
+++ b/src/bootstrap/cache.rs
@@ -161,7 +161,7 @@ impl Ord for Interned {
}
}
-struct TyIntern {
+struct TyIntern {
items: Vec,
set: HashMap>,
}
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index df1c72575846b..cadb9a7e441f2 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -55,7 +55,6 @@ impl Step for Std {
cargo,
args(builder.kind),
&libstd_stamp(builder, compiler, target),
- vec![],
true);
let libdir = builder.sysroot_libdir(compiler, target);
@@ -104,7 +103,6 @@ impl Step for Rustc {
cargo,
args(builder.kind),
&librustc_stamp(builder, compiler, target),
- vec![],
true);
let libdir = builder.sysroot_libdir(compiler, target);
@@ -157,7 +155,6 @@ impl Step for CodegenBackend {
cargo,
args(builder.kind),
&codegen_backend_stamp(builder, compiler, target, backend),
- vec![],
true);
}
}
@@ -202,7 +199,6 @@ impl Step for Rustdoc {
cargo,
args(builder.kind),
&rustdoc_stamp(builder, compiler, target),
- vec![],
true);
let libdir = builder.sysroot_libdir(compiler, target);
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index da8d43ed49b7f..6ea32edfb208b 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -69,7 +69,7 @@ impl Step for Std {
return;
}
- let mut target_deps = builder.ensure(StartupObjects { compiler, target });
+ builder.ensure(StartupObjects { compiler, target });
let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
if compiler_to_use != compiler {
@@ -91,7 +91,7 @@ impl Step for Std {
return;
}
- target_deps.extend(copy_third_party_objects(builder, &compiler, target).into_iter());
+ copy_third_party_objects(builder, &compiler, target);
let mut cargo = builder.cargo(compiler, Mode::Std, target, "build");
std_cargo(builder, &compiler, target, &mut cargo);
@@ -102,7 +102,6 @@ impl Step for Std {
cargo,
vec![],
&libstd_stamp(builder, compiler, target),
- target_deps,
false);
builder.ensure(StdLink {
@@ -114,22 +113,9 @@ impl Step for Std {
}
/// Copies third pary objects needed by various targets.
-fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target: Interned)
- -> Vec
-{
+fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target: Interned) {
let libdir = builder.sysroot_libdir(*compiler, target);
- let mut target_deps = vec![];
-
- let mut copy_and_stamp = |sourcedir: &Path, name: &str| {
- let target = libdir.join(name);
- builder.copy(
- &sourcedir.join(name),
- &target,
- );
- target_deps.push(target);
- };
-
// Copies the crt(1,i,n).o startup objects
//
// Since musl supports fully static linking, we can cross link for it even
@@ -137,13 +123,19 @@ fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target:
// files. As those shipped with glibc won't work, copy the ones provided by
// musl so we have them on linux-gnu hosts.
if target.contains("musl") {
- let srcdir = builder.musl_root(target).unwrap().join("lib");
for &obj in &["crt1.o", "crti.o", "crtn.o"] {
- copy_and_stamp(&srcdir, obj);
+ builder.copy(
+ &builder.musl_root(target).unwrap().join("lib").join(obj),
+ &libdir.join(obj),
+ );
}
} else if target.ends_with("-wasi") {
- let srcdir = builder.wasi_root(target).unwrap().join("lib/wasm32-wasi");
- copy_and_stamp(&srcdir, "crt1.o");
+ for &obj in &["crt1.o"] {
+ builder.copy(
+ &builder.wasi_root(target).unwrap().join("lib/wasm32-wasi").join(obj),
+ &libdir.join(obj),
+ );
+ }
}
// Copies libunwind.a compiled to be linked wit x86_64-fortanix-unknown-sgx.
@@ -153,11 +145,11 @@ fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target:
// which is provided by std for this target.
if target == "x86_64-fortanix-unknown-sgx" {
let src_path_env = "X86_FORTANIX_SGX_LIBS";
+ let obj = "libunwind.a";
let src = env::var(src_path_env).expect(&format!("{} not found in env", src_path_env));
- copy_and_stamp(Path::new(&src), "libunwind.a");
+ let src = Path::new(&src).join(obj);
+ builder.copy(&src, &libdir.join(obj));
}
-
- target_deps
}
/// Configure cargo to compile the standard library, adding appropriate env vars
@@ -218,6 +210,7 @@ pub fn std_cargo(builder: &Builder<'_>,
// config.toml equivalent) is used
let llvm_config = builder.ensure(native::Llvm {
target: builder.config.build,
+ emscripten: false,
});
cargo.env("LLVM_CONFIG", llvm_config);
cargo.env("RUSTC_BUILD_SANITIZERS", "1");
@@ -314,7 +307,7 @@ pub struct StartupObjects {
}
impl Step for StartupObjects {
- type Output = Vec;
+ type Output = ();
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.path("src/rtstartup")
@@ -333,15 +326,13 @@ impl Step for StartupObjects {
/// They don't require any library support as they're just plain old object
/// files, so we just use the nightly snapshot compiler to always build them (as
/// no other compilers are guaranteed to be available).
- fn run(self, builder: &Builder<'_>) -> Vec {
+ fn run(self, builder: &Builder<'_>) {
let for_compiler = self.compiler;
let target = self.target;
if !target.contains("windows-gnu") {
- return vec![]
+ return
}
- let mut target_deps = vec![];
-
let src_dir = &builder.src.join("src/rtstartup");
let dst_dir = &builder.native_dir(target).join("rtstartup");
let sysroot_dir = &builder.sysroot_libdir(for_compiler, target);
@@ -360,9 +351,7 @@ impl Step for StartupObjects {
.arg(src_file));
}
- let target = sysroot_dir.join(file.to_string() + ".o");
- builder.copy(dst_file, &target);
- target_deps.push(target);
+ builder.copy(dst_file, &sysroot_dir.join(file.to_string() + ".o"));
}
for obj in ["crt2.o", "dllcrt2.o"].iter() {
@@ -370,12 +359,8 @@ impl Step for StartupObjects {
builder.cc(target),
target,
obj);
- let target = sysroot_dir.join(obj);
- builder.copy(&src, &target);
- target_deps.push(target);
+ builder.copy(&src, &sysroot_dir.join(obj));
}
-
- target_deps
}
}
@@ -453,7 +438,6 @@ impl Step for Rustc {
cargo,
vec![],
&librustc_stamp(builder, compiler, target),
- vec![],
false);
builder.ensure(RustcLink {
@@ -602,7 +586,7 @@ impl Step for CodegenBackend {
let tmp_stamp = out_dir.join(".tmp.stamp");
- let files = run_cargo(builder, cargo, vec![], &tmp_stamp, vec![], false);
+ let files = run_cargo(builder, cargo, vec![], &tmp_stamp, false);
if builder.config.dry_run {
return;
}
@@ -631,27 +615,36 @@ pub fn build_codegen_backend(builder: &Builder<'_>,
compiler: &Compiler,
target: Interned,
backend: Interned) -> String {
+ let mut features = String::new();
+
match &*backend {
- "llvm" => {
+ "llvm" | "emscripten" => {
// Build LLVM for our target. This will implicitly build the
// host LLVM if necessary.
let llvm_config = builder.ensure(native::Llvm {
target,
+ emscripten: backend == "emscripten",
});
+ if backend == "emscripten" {
+ features.push_str(" emscripten");
+ }
+
builder.info(&format!("Building stage{} codegen artifacts ({} -> {}, {})",
compiler.stage, &compiler.host, target, backend));
// Pass down configuration from the LLVM build into the build of
// librustc_llvm and librustc_codegen_llvm.
- if builder.is_rust_llvm(target) {
+ if builder.is_rust_llvm(target) && backend != "emscripten" {
cargo.env("LLVM_RUSTLLVM", "1");
}
cargo.env("LLVM_CONFIG", &llvm_config);
- let target_config = builder.config.target_config.get(&target);
- if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
- cargo.env("CFG_LLVM_ROOT", s);
+ if backend != "emscripten" {
+ let target_config = builder.config.target_config.get(&target);
+ if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
+ cargo.env("CFG_LLVM_ROOT", s);
+ }
}
// Some LLVM linker flags (-L and -l) may be needed to link librustc_llvm.
if let Some(ref s) = builder.config.llvm_ldflags {
@@ -669,7 +662,9 @@ pub fn build_codegen_backend(builder: &Builder<'_>,
"libstdc++.a");
cargo.env("LLVM_STATIC_STDCPP", file);
}
- if builder.config.llvm_link_shared || builder.config.llvm_thin_lto {
+ if builder.config.llvm_link_shared ||
+ (builder.config.llvm_thin_lto && backend != "emscripten")
+ {
cargo.env("LLVM_LINK_SHARED", "1");
}
if builder.config.llvm_use_libcxx {
@@ -681,7 +676,8 @@ pub fn build_codegen_backend(builder: &Builder<'_>,
}
_ => panic!("unknown backend: {}", backend),
}
- String::new()
+
+ features
}
/// Creates the `codegen-backends` folder for a compiler that's about to be
@@ -958,7 +954,6 @@ pub fn run_cargo(builder: &Builder<'_>,
cargo: Cargo,
tail_args: Vec,
stamp: &Path,
- additional_target_deps: Vec,
is_check: bool)
-> Vec
{
@@ -1075,7 +1070,6 @@ pub fn run_cargo(builder: &Builder<'_>,
deps.push((path_to_add.into(), false));
}
- deps.extend(additional_target_deps.into_iter().map(|d| (d, false)));
deps.sort();
let mut new_contents = Vec::new();
for (dep, proc_macro) in deps.iter() {
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index d1bdfa0a76763..52b5cd888df9c 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -200,15 +200,16 @@ struct Build {
target: Vec,
cargo: Option,
rustc: Option,
- docs: Option,
+ low_priority: Option,
compiler_docs: Option,
+ docs: Option,
submodules: Option,
fast_submodules: Option,
gdb: Option,
- nodejs: Option,
- python: Option,
locked_deps: Option,
vendor: Option,
+ nodejs: Option,
+ python: Option,
full_bootstrap: Option,
extended: Option,
tools: Option>,
@@ -216,7 +217,6 @@ struct Build {
sanitizers: Option,
profiler: Option,
cargo_native_static: Option,
- low_priority: Option,
configure_args: Option>,
local_rebuild: Option,
print_step_timings: Option,
@@ -228,11 +228,11 @@ struct Build {
struct Install {
prefix: Option,
sysconfdir: Option,
+ datadir: Option,
docdir: Option,
bindir: Option,
libdir: Option,
mandir: Option,
- datadir: Option,
// standard paths, currently unused
infodir: Option,
@@ -243,14 +243,14 @@ struct Install {
#[derive(Deserialize, Default)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
struct Llvm {
+ ccache: Option,
+ ninja: Option,
+ assertions: Option,
optimize: Option,
thin_lto: Option,
release_debuginfo: Option,
- assertions: Option,
- ccache: Option,
version_check: Option,
static_libstdcpp: Option,
- ninja: Option,
targets: Option,
experimental_targets: Option,
link_jobs: Option,
@@ -293,7 +293,6 @@ impl Default for StringOrBool {
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
struct Rust {
optimize: Option,
- debug: Option,
codegen_units: Option,
codegen_units_std: Option,
debug_assertions: Option,
@@ -302,24 +301,25 @@ struct Rust {
debuginfo_level_std: Option,
debuginfo_level_tools: Option,
debuginfo_level_tests: Option,
- backtrace: Option,
- incremental: Option,
parallel_compiler: Option,
+ backtrace: Option,
default_linker: Option,
channel: Option,
musl_root: Option,
rpath: Option,
- verbose_tests: Option,
optimize_tests: Option,
codegen_tests: Option,
ignore_git: Option,
+ debug: Option,
dist_src: Option,
+ verbose_tests: Option,
+ incremental: Option,
save_toolstates: Option,
codegen_backends: Option>,
codegen_backends_dir: Option,
lld: Option,
- llvm_tools: Option,
lldb: Option,
+ llvm_tools: Option,
deny_warnings: Option,
backtrace_on_ice: Option,
verify_llvm_ir: Option,
@@ -333,13 +333,13 @@ struct Rust {
#[derive(Deserialize, Default)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
struct TomlTarget {
+ llvm_config: Option,
+ llvm_filecheck: Option,
cc: Option,
cxx: Option,
ar: Option,
ranlib: Option,
linker: Option,
- llvm_config: Option,
- llvm_filecheck: Option,
android_ndk: Option,
crt_static: Option,
musl_root: Option,
@@ -668,6 +668,7 @@ impl Config {
pub fn llvm_enabled(&self) -> bool {
self.rust_codegen_backends.contains(&INTERNER.intern_str("llvm"))
+ || self.rust_codegen_backends.contains(&INTERNER.intern_str("emscripten"))
}
}
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py
index 76509134f7ccd..346f0cb2039c0 100755
--- a/src/bootstrap/configure.py
+++ b/src/bootstrap/configure.py
@@ -55,6 +55,7 @@ def v(*args):
o("dist-src", "rust.dist-src", "when building tarballs enables building a source tarball")
o("cargo-native-static", "build.cargo-native-static", "static native libraries in cargo")
o("profiler", "build.profiler", "build the profiler runtime")
+o("emscripten", None, "compile the emscripten backend as well as LLVM")
o("full-tools", None, "enable all tools")
o("lld", "rust.lld", "build lld")
o("lldb", "rust.lldb", "build lldb")
@@ -334,8 +335,10 @@ def set(key, value):
set('build.host', value.split(','))
elif option.name == 'target':
set('build.target', value.split(','))
+ elif option.name == 'emscripten':
+ set('rust.codegen-backends', ['llvm', 'emscripten'])
elif option.name == 'full-tools':
- set('rust.codegen-backends', ['llvm'])
+ set('rust.codegen-backends', ['llvm', 'emscripten'])
set('rust.lld', True)
set('rust.llvm-tools', True)
set('build.extended', True)
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 93143570b0fe1..d9dff77a30e6b 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -637,28 +637,6 @@ impl Step for DebuggerScripts {
}
}
-fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool {
- // The only true set of target libraries came from the build triple, so
- // let's reduce redundant work by only producing archives from that host.
- if compiler.host != builder.config.build {
- builder.info("\tskipping, not a build host");
- true
- } else {
- false
- }
-}
-
-/// Copy stamped files into an image's `target/lib` directory.
-fn copy_target_libs(builder: &Builder<'_>, target: &str, image: &Path, stamp: &Path) {
- let dst = image.join("lib/rustlib").join(target).join("lib");
- t!(fs::create_dir_all(&dst));
- for (path, host) in builder.read_stamp_file(stamp) {
- if !host || builder.config.build == target {
- builder.copy(&path, &dst.join(path.file_name().unwrap()));
- }
- }
-}
-
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Std {
pub compiler: Compiler,
@@ -689,19 +667,44 @@ impl Step for Std {
let target = self.target;
let name = pkgname(builder, "rust-std");
- let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target));
- if skip_host_target_lib(builder, compiler) {
- return archive;
+
+ // The only true set of target libraries came from the build triple, so
+ // let's reduce redundant work by only producing archives from that host.
+ if compiler.host != builder.config.build {
+ builder.info("\tskipping, not a build host");
+ return distdir(builder).join(format!("{}-{}.tar.gz", name, target));
}
- builder.ensure(compile::Std { compiler, target });
+ // We want to package up as many target libraries as possible
+ // for the `rust-std` package, so if this is a host target we
+ // depend on librustc and otherwise we just depend on libtest.
+ if builder.hosts.iter().any(|t| t == target) {
+ builder.ensure(compile::Rustc { compiler, target });
+ } else {
+ builder.ensure(compile::Std { compiler, target });
+ }
let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
let _ = fs::remove_dir_all(&image);
- let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
- let stamp = compile::libstd_stamp(builder, compiler_to_use, target);
- copy_target_libs(builder, &target, &image, &stamp);
+ let dst = image.join("lib/rustlib").join(target);
+ t!(fs::create_dir_all(&dst));
+ let mut src = builder.sysroot_libdir(compiler, target).to_path_buf();
+ src.pop(); // Remove the trailing /lib folder from the sysroot_libdir
+ builder.cp_filtered(&src, &dst, &|path| {
+ if let Some(name) = path.file_name().and_then(|s| s.to_str()) {
+ if name == builder.config.rust_codegen_backends_dir.as_str() {
+ return false
+ }
+ if name == "bin" {
+ return false
+ }
+ if name.contains("LLVM") {
+ return false
+ }
+ }
+ true
+ });
let mut cmd = rust_installer(builder);
cmd.arg("generate")
@@ -720,73 +723,7 @@ impl Step for Std {
let _time = timeit(builder);
builder.run(&mut cmd);
builder.remove_dir(&image);
- archive
- }
-}
-
-#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
-pub struct RustcDev {
- pub compiler: Compiler,
- pub target: Interned,
-}
-
-impl Step for RustcDev {
- type Output = PathBuf;
- const DEFAULT: bool = true;
- const ONLY_HOSTS: bool = true;
-
- fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("rustc-dev")
- }
-
- fn make_run(run: RunConfig<'_>) {
- run.builder.ensure(RustcDev {
- compiler: run.builder.compiler_for(
- run.builder.top_stage,
- run.builder.config.build,
- run.target,
- ),
- target: run.target,
- });
- }
-
- fn run(self, builder: &Builder<'_>) -> PathBuf {
- let compiler = self.compiler;
- let target = self.target;
-
- let name = pkgname(builder, "rustc-dev");
- let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target));
- if skip_host_target_lib(builder, compiler) {
- return archive;
- }
-
- builder.ensure(compile::Rustc { compiler, target });
-
- let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
- let _ = fs::remove_dir_all(&image);
-
- let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
- let stamp = compile::librustc_stamp(builder, compiler_to_use, target);
- copy_target_libs(builder, &target, &image, &stamp);
-
- let mut cmd = rust_installer(builder);
- cmd.arg("generate")
- .arg("--product-name=Rust")
- .arg("--rel-manifest-dir=rustlib")
- .arg("--success-message=Rust-is-ready-to-develop.")
- .arg("--image-dir").arg(&image)
- .arg("--work-dir").arg(&tmpdir(builder))
- .arg("--output-dir").arg(&distdir(builder))
- .arg(format!("--package-name={}-{}", name, target))
- .arg(format!("--component-name=rustc-dev-{}", target))
- .arg("--legacy-manifest-dirs=rustlib,cargo");
-
- builder.info(&format!("Dist rustc-dev stage{} ({} -> {})",
- compiler.stage, &compiler.host, target));
- let _time = timeit(builder);
- builder.run(&mut cmd);
- builder.remove_dir(&image);
- archive
+ distdir(builder).join(format!("{}-{}.tar.gz", name, target))
}
}
@@ -889,6 +826,7 @@ fn copy_src_dirs(builder: &Builder<'_>, src_dirs: &[&str], exclude_dirs: &[&str]
const LLVM_TEST: &[&str] = &[
"llvm-project/llvm/test", "llvm-project\\llvm\\test",
+ "llvm-emscripten/test", "llvm-emscripten\\test",
];
if LLVM_TEST.iter().any(|path| spath.contains(path)) &&
(spath.ends_with(".ll") ||
@@ -896,6 +834,9 @@ fn copy_src_dirs(builder: &Builder<'_>, src_dirs: &[&str], exclude_dirs: &[&str]
spath.ends_with(".s")) {
return false
}
+ if spath.contains("test/emscripten") || spath.contains("test\\emscripten") {
+ return false
+ }
let full_path = Path::new(dir).join(path);
if exclude_dirs.iter().any(|excl| full_path == Path::new(excl)) {
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index d1cf1cbca7844..9203a558f6465 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -232,6 +232,7 @@ pub struct Build {
miri_info: channel::GitInfo,
rustfmt_info: channel::GitInfo,
in_tree_llvm_info: channel::GitInfo,
+ emscripten_llvm_info: channel::GitInfo,
local_rebuild: bool,
fail_fast: bool,
doc_tests: DocTests,
@@ -350,6 +351,7 @@ impl Build {
// we always try to use git for LLVM builds
let in_tree_llvm_info = channel::GitInfo::new(false, &src.join("src/llvm-project"));
+ let emscripten_llvm_info = channel::GitInfo::new(false, &src.join("src/llvm-emscripten"));
let mut build = Build {
initial_rustc: config.initial_rustc.clone(),
@@ -374,6 +376,7 @@ impl Build {
miri_info,
rustfmt_info,
in_tree_llvm_info,
+ emscripten_llvm_info,
cc: HashMap::new(),
cxx: HashMap::new(),
ar: HashMap::new(),
@@ -550,6 +553,10 @@ impl Build {
self.out.join(&*target).join("llvm")
}
+ fn emscripten_llvm_out(&self, target: Interned) -> PathBuf {
+ self.out.join(&*target).join("llvm-emscripten")
+ }
+
fn lld_out(&self, target: Interned) -> PathBuf {
self.out.join(&*target).join("lld")
}
@@ -1119,7 +1126,7 @@ impl Build {
}
let mut paths = Vec::new();
- let contents = t!(fs::read(stamp), &stamp);
+ let contents = t!(fs::read(stamp));
// This is the method we use for extracting paths from the stamp file passed to us. See
// run_cargo for more information (in compile.rs).
for part in contents.split(|b| *b == 0) {
@@ -1137,7 +1144,6 @@ impl Build {
pub fn copy(&self, src: &Path, dst: &Path) {
if self.config.dry_run { return; }
self.verbose_than(1, &format!("Copy {:?} to {:?}", src, dst));
- if src == dst { return; }
let _ = fs::remove_file(&dst);
let metadata = t!(src.symlink_metadata());
if metadata.file_type().is_symlink() {
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 97cdd25680162..7bf9ea2688f4c 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -28,6 +28,7 @@ use crate::GitRepo;
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Llvm {
pub target: Interned,
+ pub emscripten: bool,
}
impl Step for Llvm {
@@ -39,35 +40,46 @@ impl Step for Llvm {
run.path("src/llvm-project")
.path("src/llvm-project/llvm")
.path("src/llvm")
+ .path("src/llvm-emscripten")
}
fn make_run(run: RunConfig<'_>) {
+ let emscripten = run.path.ends_with("llvm-emscripten");
run.builder.ensure(Llvm {
target: run.target,
+ emscripten,
});
}
/// Compile LLVM for `target`.
fn run(self, builder: &Builder<'_>) -> PathBuf {
let target = self.target;
+ let emscripten = self.emscripten;
// If we're using a custom LLVM bail out here, but we can only use a
// custom LLVM for the build triple.
- if let Some(config) = builder.config.target_config.get(&target) {
- if let Some(ref s) = config.llvm_config {
- check_llvm_version(builder, s);
- return s.to_path_buf()
+ if !self.emscripten {
+ if let Some(config) = builder.config.target_config.get(&target) {
+ if let Some(ref s) = config.llvm_config {
+ check_llvm_version(builder, s);
+ return s.to_path_buf()
+ }
}
}
- let llvm_info = &builder.in_tree_llvm_info;
- let root = "src/llvm-project/llvm";
- let out_dir = builder.llvm_out(target);
- let mut llvm_config_ret_dir = builder.llvm_out(builder.config.build);
- if !builder.config.build.contains("msvc") || builder.config.ninja {
- llvm_config_ret_dir.push("build");
- }
- llvm_config_ret_dir.push("bin");
+ let (llvm_info, root, out_dir, llvm_config_ret_dir) = if emscripten {
+ let info = &builder.emscripten_llvm_info;
+ let dir = builder.emscripten_llvm_out(target);
+ let config_dir = dir.join("bin");
+ (info, "src/llvm-emscripten", dir, config_dir)
+ } else {
+ let info = &builder.in_tree_llvm_info;
+ let mut dir = builder.llvm_out(builder.config.build);
+ if !builder.config.build.contains("msvc") || builder.config.ninja {
+ dir.push("build");
+ }
+ (info, "src/llvm-project/llvm", builder.llvm_out(target), dir.join("bin"))
+ };
let build_llvm_config = llvm_config_ret_dir
.join(exe("llvm-config", &*builder.config.build));
@@ -95,7 +107,8 @@ impl Step for Llvm {
}
}
- builder.info(&format!("Building LLVM for {}", target));
+ let descriptor = if emscripten { "Emscripten " } else { "" };
+ builder.info(&format!("Building {}LLVM for {}", descriptor, target));
let _time = util::timeit(&builder);
t!(fs::create_dir_all(&out_dir));
@@ -110,15 +123,23 @@ impl Step for Llvm {
// NOTE: remember to also update `config.toml.example` when changing the
// defaults!
- let llvm_targets = match &builder.config.llvm_targets {
- Some(s) => s,
- None => "AArch64;ARM;Hexagon;MSP430;Mips;NVPTX;PowerPC;RISCV;\
- Sparc;SystemZ;WebAssembly;X86",
+ let llvm_targets = if self.emscripten {
+ "JSBackend"
+ } else {
+ match builder.config.llvm_targets {
+ Some(ref s) => s,
+ None => "AArch64;ARM;Hexagon;MSP430;Mips;NVPTX;PowerPC;RISCV;\
+ Sparc;SystemZ;WebAssembly;X86",
+ }
};
- let llvm_exp_targets = match builder.config.llvm_experimental_targets {
- Some(ref s) => s,
- None => "",
+ let llvm_exp_targets = if self.emscripten {
+ ""
+ } else {
+ match builder.config.llvm_experimental_targets {
+ Some(ref s) => s,
+ None => "",
+ }
};
let assertions = if builder.config.llvm_assertions {"ON"} else {"OFF"};
@@ -136,29 +157,39 @@ impl Step for Llvm {
.define("WITH_POLLY", "OFF")
.define("LLVM_ENABLE_TERMINFO", "OFF")
.define("LLVM_ENABLE_LIBEDIT", "OFF")
- .define("LLVM_ENABLE_BINDINGS", "OFF")
.define("LLVM_ENABLE_Z3_SOLVER", "OFF")
.define("LLVM_PARALLEL_COMPILE_JOBS", builder.jobs().to_string())
.define("LLVM_TARGET_ARCH", target.split('-').next().unwrap())
.define("LLVM_DEFAULT_TARGET_TRIPLE", target);
- if builder.config.llvm_thin_lto {
+ if builder.config.llvm_thin_lto && !emscripten {
cfg.define("LLVM_ENABLE_LTO", "Thin");
if !target.contains("apple") {
cfg.define("LLVM_ENABLE_LLD", "ON");
}
}
+ // By default, LLVM will automatically find OCaml and, if it finds it,
+ // install the LLVM bindings in LLVM_OCAML_INSTALL_PATH, which defaults
+ // to /usr/bin/ocaml.
+ // This causes problem for non-root builds of Rust. Side-step the issue
+ // by setting LLVM_OCAML_INSTALL_PATH to a relative path, so it installs
+ // in the prefix.
+ cfg.define("LLVM_OCAML_INSTALL_PATH",
+ env::var_os("LLVM_OCAML_INSTALL_PATH").unwrap_or_else(|| "usr/lib/ocaml".into()));
+
+ let want_lldb = builder.config.lldb_enabled && !self.emscripten;
+
// This setting makes the LLVM tools link to the dynamic LLVM library,
// which saves both memory during parallel links and overall disk space
// for the tools. We don't do this on every platform as it doesn't work
// equally well everywhere.
- if builder.llvm_link_tools_dynamically(target) {
+ if builder.llvm_link_tools_dynamically(target) && !emscripten {
cfg.define("LLVM_LINK_LLVM_DYLIB", "ON");
}
// For distribution we want the LLVM tools to be *statically* linked to libstdc++
- if builder.config.llvm_tools_enabled || builder.config.lldb_enabled {
+ if builder.config.llvm_tools_enabled || want_lldb {
if !target.contains("windows") {
if target.contains("apple") {
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-static-libstdc++");
@@ -186,7 +217,7 @@ impl Step for Llvm {
enabled_llvm_projects.push("compiler-rt");
}
- if builder.config.lldb_enabled {
+ if want_lldb {
enabled_llvm_projects.push("clang");
enabled_llvm_projects.push("lldb");
// For the time being, disable code signing.
@@ -211,9 +242,10 @@ impl Step for Llvm {
}
// http://llvm.org/docs/HowToCrossCompileLLVM.html
- if target != builder.config.build {
+ if target != builder.config.build && !emscripten {
builder.ensure(Llvm {
target: builder.config.build,
+ emscripten: false,
});
// FIXME: if the llvm root for the build triple is overridden then we
// should use llvm-tblgen from there, also should verify that it
@@ -457,6 +489,7 @@ impl Step for Lld {
let llvm_config = builder.ensure(Llvm {
target: self.target,
+ emscripten: false,
});
let out_dir = builder.lld_out(target);
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 7ed67c6c7c5d5..b7ce9c7b39709 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -427,7 +427,7 @@ impl Step for Miri {
// (We do this separately from the above so that when the setup actually
// happens we get some output.)
// We re-use the `cargo` from above.
- cargo.arg("--print-sysroot");
+ cargo.arg("--env");
// FIXME: Is there a way in which we can re-use the usual `run` helpers?
let miri_sysroot = if builder.config.dry_run {
@@ -437,11 +437,13 @@ impl Step for Miri {
let out = cargo.output()
.expect("We already ran `cargo miri setup` before and that worked");
assert!(out.status.success(), "`cargo miri setup` returned with non-0 exit code");
- // Output is "\n".
+ // Output is "MIRI_SYSROOT=\n".
let stdout = String::from_utf8(out.stdout)
.expect("`cargo miri setup` stdout is not valid UTF-8");
- let sysroot = stdout.trim_end();
- builder.verbose(&format!("`cargo miri setup --print-sysroot` said: {:?}", sysroot));
+ let stdout = stdout.trim();
+ builder.verbose(&format!("`cargo miri setup --env` returned: {:?}", stdout));
+ let sysroot = stdout.splitn(2, '=')
+ .nth(1).expect("`cargo miri setup` stdout did not contain '='");
sysroot.to_owned()
};
@@ -1045,11 +1047,10 @@ impl Step for Compiletest {
// Also provide `rust_test_helpers` for the host.
builder.ensure(native::TestHelpers { target: compiler.host });
- // As well as the target, except for plain wasm32, which can't build it
- if !target.contains("wasm32") || target.contains("emscripten") {
+ // wasm32 can't build the test helpers
+ if !target.contains("wasm32") {
builder.ensure(native::TestHelpers { target });
}
-
builder.ensure(RemoteCopyLibs { compiler, target });
let mut cmd = builder.tool_cmd(Tool::Compiletest);
@@ -1163,7 +1164,7 @@ impl Step for Compiletest {
}).to_string()
})
};
- let lldb_exe = if builder.config.lldb_enabled {
+ let lldb_exe = if builder.config.lldb_enabled && !target.contains("emscripten") {
// Test against the lldb that was just built.
builder.llvm_out(target).join("bin").join("lldb")
} else {
@@ -1232,6 +1233,7 @@ impl Step for Compiletest {
if builder.config.llvm_enabled() {
let llvm_config = builder.ensure(native::Llvm {
target: builder.config.build,
+ emscripten: false,
});
if !builder.config.dry_run {
let llvm_version = output(Command::new(&llvm_config).arg("--version"));
diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs
index bb94fb2b755f5..f035a7119188a 100644
--- a/src/build_helper/lib.rs
+++ b/src/build_helper/lib.rs
@@ -21,13 +21,6 @@ macro_rules! t {
Err(e) => panic!("{} failed with {}", stringify!($e), e),
}
};
- // it can show extra info in the second parameter
- ($e:expr, $extra:expr) => {
- match $e {
- Ok(e) => e,
- Err(e) => panic!("{} failed with {} ({:?})", stringify!($e), e, $extra),
- }
- };
}
// Because Cargo adds the compiler's dylib path to our library search path, llvm-config may
diff --git a/src/ci/azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml
index 4442afc98e406..5f7761297095c 100644
--- a/src/ci/azure-pipelines/auto.yml
+++ b/src/ci/azure-pipelines/auto.yml
@@ -124,14 +124,14 @@ jobs:
IMAGE: dist-x86_64-netbsd
DEPLOY: 1
+ asmjs:
+ IMAGE: asmjs
i686-gnu:
IMAGE: i686-gnu
i686-gnu-nopt:
IMAGE: i686-gnu-nopt
test-various:
IMAGE: test-various
- wasm32:
- IMAGE: wasm32
x86_64-gnu:
IMAGE: x86_64-gnu
x86_64-gnu-full-bootstrap:
diff --git a/src/ci/azure-pipelines/steps/install-windows-build-deps.yml b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml
index 812339900fe42..bd4f1ed0cea43 100644
--- a/src/ci/azure-pipelines/steps/install-windows-build-deps.yml
+++ b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml
@@ -84,17 +84,6 @@ steps:
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), ne(variables['MINGW_URL'],''))
displayName: Download custom MinGW
-# FIXME(#65767): workaround msys bug, step 1
-- bash: |
- set -e
- arch=i686
- if [ "$MSYS_BITS" = "64" ]; then
- arch=x86_64
- fi
- curl -O https://ci-mirrors.rust-lang.org/rustc/msys2-repo/mingw/$arch/mingw-w64-$arch-ca-certificates-20180409-1-any.pkg.tar.xz
- condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
- displayName: Download working ca-certificates for msys
-
# Otherwise install MinGW through `pacman`
- bash: |
set -e
@@ -107,18 +96,6 @@ steps:
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), eq(variables['MINGW_URL'],''))
displayName: Download standard MinGW
-# FIXME(#65767): workaround msys bug, step 2
-- bash: |
- set -e
- arch=i686
- if [ "$MSYS_BITS" = "64" ]; then
- arch=x86_64
- fi
- pacman -U --noconfirm --noprogressbar mingw-w64-$arch-ca-certificates-20180409-1-any.pkg.tar.xz
- rm mingw-w64-$arch-ca-certificates-20180409-1-any.pkg.tar.xz
- condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
- displayName: Install working ca-certificates for msys
-
# Make sure we use the native python interpreter instead of some msys equivalent
# one way or another. The msys interpreters seem to have weird path conversions
# baked in which break LLVM's build system one way or another, so let's use the
diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md
index a2d83eca24b0a..367e43849923f 100644
--- a/src/ci/docker/README.md
+++ b/src/ci/docker/README.md
@@ -165,7 +165,8 @@ For targets: `arm-unknown-linux-gnueabihf`
For targets: `armv7-unknown-linux-gnueabihf`
- Path and misc options > Prefix directory = /x-tools/${CT\_TARGET}
-- Path and misc options > Patches origin = Bundled only
+- Path and misc options > Patches origin = Bundled, then local
+- Path and misc options > Local patch directory = /tmp/patches
- Target options > Target Architecture = arm
- Target options > Suffix to the arch-part = v7
- Target options > Architecture level = armv7-a -- (+)
@@ -173,9 +174,9 @@ For targets: `armv7-unknown-linux-gnueabihf`
- Target options > Floating point = hardware (FPU) -- (\*)
- Target options > Default instruction set mode = thumb -- (\*)
- Operating System > Target OS = linux
-- Operating System > Linux kernel version = 3.2.101
-- C-library > glibc version = 2.17.0
-- C compiler > gcc version = 8.3.0
+- Operating System > Linux kernel version = 3.2.72 -- Precise kernel
+- C-library > glibc version = 2.16.0
+- C compiler > gcc version = 5.2.0
- C compiler > C++ = ENABLE -- to cross compile LLVM
(\*) These options have been selected to match the configuration of the arm
diff --git a/src/ci/docker/asmjs/Dockerfile b/src/ci/docker/asmjs/Dockerfile
new file mode 100644
index 0000000000000..3abaab6b34ef0
--- /dev/null
+++ b/src/ci/docker/asmjs/Dockerfile
@@ -0,0 +1,47 @@
+FROM ubuntu:16.04
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ g++ \
+ make \
+ file \
+ curl \
+ ca-certificates \
+ python \
+ git \
+ cmake \
+ sudo \
+ gdb \
+ xz-utils
+
+COPY scripts/emscripten.sh /scripts/
+RUN bash /scripts/emscripten.sh
+
+COPY scripts/sccache.sh /scripts/
+RUN sh /scripts/sccache.sh
+
+ENV PATH=$PATH:/emsdk-portable
+ENV PATH=$PATH:/emsdk-portable/clang/e1.38.15_64bit/
+ENV PATH=$PATH:/emsdk-portable/emscripten/1.38.15/
+ENV PATH=$PATH:/emsdk-portable/node/8.9.1_64bit/bin/
+ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.38.15/
+ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.38.15_64bit/binaryen/
+ENV EM_CONFIG=/emsdk-portable/.emscripten
+
+ENV TARGETS=asmjs-unknown-emscripten
+
+ENV RUST_CONFIGURE_ARGS --enable-emscripten --disable-optimize-tests
+
+ENV SCRIPT python2.7 ../x.py test --target $TARGETS \
+ src/test/ui \
+ src/test/run-fail \
+ src/libstd \
+ src/liballoc \
+ src/libcore
+
+# Debug assertions in rustc are largely covered by other builders, and LLVM
+# assertions cause this builder to slow down by quite a large amount and don't
+# buy us a huge amount over other builders (not sure if we've ever seen an
+# asmjs-specific backend assertion trip), so disable assertions for these
+# tests.
+ENV NO_LLVM_ASSERTIONS=1
+ENV NO_DEBUG_ASSERTIONS=1
diff --git a/src/ci/docker/disabled/asmjs/Dockerfile b/src/ci/docker/disabled/asmjs/Dockerfile
deleted file mode 100644
index e27a2a529a8ca..0000000000000
--- a/src/ci/docker/disabled/asmjs/Dockerfile
+++ /dev/null
@@ -1,41 +0,0 @@
-FROM ubuntu:16.04
-
-RUN apt-get update && apt-get install -y --no-install-recommends \
- g++ \
- make \
- file \
- curl \
- ca-certificates \
- python \
- git \
- cmake \
- sudo \
- gdb \
- xz-utils \
- bzip2
-
-COPY scripts/emscripten.sh /scripts/
-RUN bash /scripts/emscripten.sh
-
-COPY scripts/sccache.sh /scripts/
-RUN sh /scripts/sccache.sh
-
-ENV PATH=$PATH:/emsdk-portable
-ENV PATH=$PATH:/emsdk-portable/upstream/emscripten/
-ENV PATH=$PATH:/emsdk-portable/node/12.9.1_64bit/bin/
-ENV BINARYEN_ROOT=/emsdk-portable/upstream/
-
-ENV TARGETS=asmjs-unknown-emscripten
-
-# Use -O1 optimizations in the link step to reduce time spent optimizing JS.
-ENV EMCC_CFLAGS=-O1
-
-# Emscripten installation is user-specific
-ENV NO_CHANGE_USER=1
-
-ENV SCRIPT python2.7 ../x.py test --target $TARGETS
-
-# This is almost identical to the wasm32-unknown-emscripten target, so
-# running with assertions again is not useful
-ENV NO_DEBUG_ASSERTIONS=1
-ENV NO_LLVM_ASSERTIONS=1
diff --git a/src/ci/docker/disabled/wasm32-exp/Dockerfile b/src/ci/docker/disabled/wasm32-exp/Dockerfile
new file mode 100644
index 0000000000000..420d47b314c0f
--- /dev/null
+++ b/src/ci/docker/disabled/wasm32-exp/Dockerfile
@@ -0,0 +1,35 @@
+FROM ubuntu:16.04
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ g++ \
+ make \
+ file \
+ curl \
+ ca-certificates \
+ python \
+ git \
+ cmake \
+ sudo \
+ gdb \
+ xz-utils \
+ jq \
+ bzip2
+
+# emscripten
+COPY scripts/emscripten-wasm.sh /scripts/
+COPY wasm32-exp/node.sh /usr/local/bin/node
+RUN bash /scripts/emscripten-wasm.sh
+
+# cache
+COPY scripts/sccache.sh /scripts/
+RUN sh /scripts/sccache.sh
+
+# env
+ENV PATH=/wasm-install/emscripten:/wasm-install/bin:$PATH
+ENV EM_CONFIG=/root/.emscripten
+
+ENV TARGETS=wasm32-experimental-emscripten
+
+ENV RUST_CONFIGURE_ARGS --experimental-targets=WebAssembly
+
+ENV SCRIPT python2.7 ../x.py test --target $TARGETS
diff --git a/src/ci/docker/disabled/wasm32-exp/node.sh b/src/ci/docker/disabled/wasm32-exp/node.sh
new file mode 100755
index 0000000000000..aa938971c702f
--- /dev/null
+++ b/src/ci/docker/disabled/wasm32-exp/node.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+path="$(dirname $1)"
+file="$(basename $1)"
+
+shift
+
+cd "$path"
+exec /node-v8.0.0-linux-x64/bin/node "$file" "$@"
diff --git a/src/ci/docker/disabled/wasm32/Dockerfile b/src/ci/docker/disabled/wasm32/Dockerfile
new file mode 100644
index 0000000000000..0d2bd39303ef8
--- /dev/null
+++ b/src/ci/docker/disabled/wasm32/Dockerfile
@@ -0,0 +1,32 @@
+FROM ubuntu:16.04
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ g++ \
+ make \
+ file \
+ curl \
+ ca-certificates \
+ python \
+ git \
+ cmake \
+ sudo \
+ gdb \
+ xz-utils
+
+# emscripten
+COPY scripts/emscripten.sh /scripts/
+RUN bash /scripts/emscripten.sh
+
+COPY scripts/sccache.sh /scripts/
+RUN sh /scripts/sccache.sh
+
+ENV PATH=$PATH:/emsdk-portable
+ENV PATH=$PATH:/emsdk-portable/clang/e1.38.15_64bit/
+ENV PATH=$PATH:/emsdk-portable/emscripten/1.38.15/
+ENV PATH=$PATH:/emsdk-portable/node/8.9.1_64bit/bin/
+ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.38.15/
+ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.38.15_64bit/binaryen/
+ENV EM_CONFIG=/emsdk-portable/.emscripten
+
+ENV TARGETS=wasm32-unknown-emscripten
+ENV SCRIPT python2.7 ../x.py test --target $TARGETS
diff --git a/src/ci/docker/dist-armv7-linux/Dockerfile b/src/ci/docker/dist-armv7-linux/Dockerfile
index 417171a861d4a..170b8134d3edc 100644
--- a/src/ci/docker/dist-armv7-linux/Dockerfile
+++ b/src/ci/docker/dist-armv7-linux/Dockerfile
@@ -3,7 +3,12 @@ FROM ubuntu:16.04
COPY scripts/cross-apt-packages.sh /scripts/
RUN sh /scripts/cross-apt-packages.sh
-COPY dist-armv7-linux/crosstool-ng.sh /scripts/
+# Ubuntu 16.04 (this container) ships with make 4, but something in the
+# toolchains we build below chokes on that, so go back to make 3
+COPY scripts/make3.sh /scripts/
+RUN sh /scripts/make3.sh
+
+COPY scripts/crosstool-ng.sh /scripts/
RUN sh /scripts/crosstool-ng.sh
COPY scripts/rustbuild-setup.sh /scripts/
@@ -11,6 +16,7 @@ RUN sh /scripts/rustbuild-setup.sh
USER rustbuild
WORKDIR /tmp
+COPY dist-armv7-linux/patches/ /tmp/patches/
COPY dist-armv7-linux/build-toolchains.sh dist-armv7-linux/armv7-linux-gnueabihf.config /tmp/
RUN ./build-toolchains.sh
diff --git a/src/ci/docker/dist-armv7-linux/armv7-linux-gnueabihf.config b/src/ci/docker/dist-armv7-linux/armv7-linux-gnueabihf.config
index 81b3d7477ec8d..5cccfd8444d35 100644
--- a/src/ci/docker/dist-armv7-linux/armv7-linux-gnueabihf.config
+++ b/src/ci/docker/dist-armv7-linux/armv7-linux-gnueabihf.config
@@ -1,32 +1,9 @@
#
# Automatically generated file; DO NOT EDIT.
-# crosstool-NG Configuration
-#
-CT_CONFIGURE_has_static_link=y
-CT_CONFIGURE_has_cxx11=y
-CT_CONFIGURE_has_wget=y
-CT_CONFIGURE_has_curl=y
-CT_CONFIGURE_has_make_3_81_or_newer=y
-CT_CONFIGURE_has_make_4_0_or_newer=y
-CT_CONFIGURE_has_libtool_2_4_or_newer=y
-CT_CONFIGURE_has_libtoolize_2_4_or_newer=y
-CT_CONFIGURE_has_autoconf_2_65_or_newer=y
-CT_CONFIGURE_has_autoreconf_2_65_or_newer=y
-CT_CONFIGURE_has_automake_1_15_or_newer=y
-CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y
-CT_CONFIGURE_has_python_3_4_or_newer=y
-CT_CONFIGURE_has_bison_2_7_or_newer=y
-CT_CONFIGURE_has_python=y
-CT_CONFIGURE_has_dtc=y
-CT_CONFIGURE_has_svn=y
-CT_CONFIGURE_has_git=y
-CT_CONFIGURE_has_md5sum=y
-CT_CONFIGURE_has_sha1sum=y
-CT_CONFIGURE_has_sha256sum=y
-CT_CONFIGURE_has_sha512sum=y
-CT_CONFIGURE_has_install_with_strip_program=y
-CT_CONFIG_VERSION_CURRENT="3"
-CT_CONFIG_VERSION="3"
+# Crosstool-NG Configuration
+#
+CT_CONFIGURE_has_make381=y
+CT_CONFIGURE_has_xz=y
CT_MODULES=y
#
@@ -44,46 +21,40 @@ CT_MODULES=y
# Paths
#
CT_LOCAL_TARBALLS_DIR=""
-# CT_TARBALLS_BUILDROOT_LAYOUT is not set
CT_WORK_DIR="${CT_TOP_DIR}/.build"
-CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}"
CT_PREFIX_DIR="/x-tools/${CT_TARGET}"
+CT_INSTALL_DIR="${CT_PREFIX_DIR}"
CT_RM_RF_PREFIX_DIR=y
CT_REMOVE_DOCS=y
-CT_INSTALL_LICENSES=y
-CT_PREFIX_DIR_RO=y
+CT_INSTALL_DIR_RO=y
CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set
#
# Downloading
#
-CT_DOWNLOAD_AGENT_WGET=y
-# CT_DOWNLOAD_AGENT_CURL is not set
-# CT_DOWNLOAD_AGENT_NONE is not set
# CT_FORBID_DOWNLOAD is not set
# CT_FORCE_DOWNLOAD is not set
CT_CONNECT_TIMEOUT=10
-CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary"
# CT_ONLY_DOWNLOAD is not set
# CT_USE_MIRROR is not set
-CT_VERIFY_DOWNLOAD_DIGEST=y
-CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y
-# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set
-# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set
-# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set
-CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512"
-# CT_VERIFY_DOWNLOAD_SIGNATURE is not set
#
# Extracting
#
# CT_FORCE_EXTRACT is not set
-CT_OVERRIDE_CONFIG_GUESS_SUB=y
+CT_OVERIDE_CONFIG_GUESS_SUB=y
# CT_ONLY_EXTRACT is not set
-CT_PATCH_BUNDLED=y
-# CT_PATCH_BUNDLED_LOCAL is not set
-CT_PATCH_ORDER="bundled"
+# CT_PATCH_BUNDLED is not set
+# CT_PATCH_LOCAL is not set
+CT_PATCH_BUNDLED_LOCAL=y
+# CT_PATCH_LOCAL_BUNDLED is not set
+# CT_PATCH_BUNDLED_FALLBACK_LOCAL is not set
+# CT_PATCH_LOCAL_FALLBACK_BUNDLED is not set
+# CT_PATCH_NONE is not set
+CT_PATCH_ORDER="bundled,local"
+CT_PATCH_USE_LOCAL=y
+CT_LOCAL_PATCH_DIR="/tmp/patches"
#
# Build behavior
@@ -119,81 +90,86 @@ CT_LOG_FILE_COMPRESS=y
#
# Target options
#
-# CT_ARCH_ALPHA is not set
-# CT_ARCH_ARC is not set
-CT_ARCH_ARM=y
-# CT_ARCH_AVR is not set
-# CT_ARCH_M68K is not set
-# CT_ARCH_MIPS is not set
-# CT_ARCH_NIOS2 is not set
-# CT_ARCH_POWERPC is not set
-# CT_ARCH_S390 is not set
-# CT_ARCH_SH is not set
-# CT_ARCH_SPARC is not set
-# CT_ARCH_X86 is not set
-# CT_ARCH_XTENSA is not set
CT_ARCH="arm"
-CT_ARCH_CHOICE_KSYM="ARM"
+CT_ARCH_SUPPORTS_BOTH_MMU=y
+CT_ARCH_SUPPORTS_BOTH_ENDIAN=y
+CT_ARCH_SUPPORTS_32=y
+CT_ARCH_SUPPORTS_64=y
+CT_ARCH_SUPPORTS_WITH_ARCH=y
+CT_ARCH_SUPPORTS_WITH_CPU=y
+CT_ARCH_SUPPORTS_WITH_TUNE=y
+CT_ARCH_SUPPORTS_WITH_FLOAT=y
+CT_ARCH_SUPPORTS_WITH_FPU=y
+CT_ARCH_SUPPORTS_SOFTFP=y
+CT_ARCH_DEFAULT_HAS_MMU=y
+CT_ARCH_DEFAULT_LE=y
+CT_ARCH_DEFAULT_32=y
+CT_ARCH_ARCH="armv7-a"
CT_ARCH_CPU=""
CT_ARCH_TUNE=""
-CT_ARCH_ARM_SHOW=y
-
-#
-# Options for arm
-#
-CT_ARCH_ARM_PKG_KSYM=""
-CT_ARCH_ARM_MODE="thumb"
-# CT_ARCH_ARM_MODE_ARM is not set
-CT_ARCH_ARM_MODE_THUMB=y
-# CT_ARCH_ARM_INTERWORKING is not set
-CT_ARCH_ARM_EABI_FORCE=y
-CT_ARCH_ARM_EABI=y
-CT_ARCH_ARM_TUPLE_USE_EABIHF=y
-CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA"
+CT_ARCH_FPU="vfpv3-d16"
+# CT_ARCH_BE is not set
+CT_ARCH_LE=y
+CT_ARCH_32=y
+# CT_ARCH_64 is not set
+CT_ARCH_BITNESS=32
+CT_ARCH_FLOAT_HW=y
+# CT_ARCH_FLOAT_SW is not set
+CT_TARGET_CFLAGS=""
+CT_TARGET_LDFLAGS=""
+# CT_ARCH_alpha is not set
+CT_ARCH_arm=y
+# CT_ARCH_avr is not set
+# CT_ARCH_m68k is not set
+# CT_ARCH_mips is not set
+# CT_ARCH_nios2 is not set
+# CT_ARCH_powerpc is not set
+# CT_ARCH_s390 is not set
+# CT_ARCH_sh is not set
+# CT_ARCH_sparc is not set
+# CT_ARCH_x86 is not set
+# CT_ARCH_xtensa is not set
+CT_ARCH_alpha_AVAILABLE=y
+CT_ARCH_arm_AVAILABLE=y
+CT_ARCH_avr_AVAILABLE=y
+CT_ARCH_m68k_AVAILABLE=y
+CT_ARCH_microblaze_AVAILABLE=y
+CT_ARCH_mips_AVAILABLE=y
+CT_ARCH_nios2_AVAILABLE=y
+CT_ARCH_powerpc_AVAILABLE=y
+CT_ARCH_s390_AVAILABLE=y
+CT_ARCH_sh_AVAILABLE=y
+CT_ARCH_sparc_AVAILABLE=y
+CT_ARCH_x86_AVAILABLE=y
+CT_ARCH_xtensa_AVAILABLE=y
CT_ARCH_SUFFIX="v7"
-# CT_OMIT_TARGET_VENDOR is not set
#
# Generic target options
#
# CT_MULTILIB is not set
-CT_DEMULTILIB=y
-CT_ARCH_SUPPORTS_BOTH_MMU=y
-CT_ARCH_DEFAULT_HAS_MMU=y
CT_ARCH_USE_MMU=y
-CT_ARCH_SUPPORTS_FLAT_FORMAT=y
-CT_ARCH_SUPPORTS_EITHER_ENDIAN=y
-CT_ARCH_DEFAULT_LE=y
-# CT_ARCH_BE is not set
-CT_ARCH_LE=y
CT_ARCH_ENDIAN="little"
-CT_ARCH_SUPPORTS_32=y
-CT_ARCH_SUPPORTS_64=y
-CT_ARCH_DEFAULT_32=y
-CT_ARCH_BITNESS=32
-CT_ARCH_32=y
-# CT_ARCH_64 is not set
#
# Target optimisations
#
-CT_ARCH_SUPPORTS_WITH_ARCH=y
-CT_ARCH_SUPPORTS_WITH_CPU=y
-CT_ARCH_SUPPORTS_WITH_TUNE=y
-CT_ARCH_SUPPORTS_WITH_FLOAT=y
-CT_ARCH_SUPPORTS_WITH_FPU=y
-CT_ARCH_SUPPORTS_SOFTFP=y
CT_ARCH_EXCLUSIVE_WITH_CPU=y
-CT_ARCH_ARCH="armv7-a"
-CT_ARCH_FPU="vfpv3-d16"
# CT_ARCH_FLOAT_AUTO is not set
-CT_ARCH_FLOAT_HW=y
# CT_ARCH_FLOAT_SOFTFP is not set
-# CT_ARCH_FLOAT_SW is not set
-CT_TARGET_CFLAGS=""
-CT_TARGET_LDFLAGS=""
CT_ARCH_FLOAT="hard"
+#
+# arm other options
+#
+CT_ARCH_ARM_MODE="thumb"
+# CT_ARCH_ARM_MODE_ARM is not set
+CT_ARCH_ARM_MODE_THUMB=y
+# CT_ARCH_ARM_INTERWORKING is not set
+CT_ARCH_ARM_EABI_FORCE=y
+CT_ARCH_ARM_EABI=y
+CT_ARCH_ARM_TUPLE_USE_EABIHF=y
+
#
# Toolchain options
#
@@ -206,9 +182,7 @@ CT_USE_SYSROOT=y
CT_SYSROOT_NAME="sysroot"
CT_SYSROOT_DIR_PREFIX=""
CT_WANTS_STATIC_LINK=y
-CT_WANTS_STATIC_LINK_CXX=y
# CT_STATIC_TOOLCHAIN is not set
-CT_SHOW_CT_VERSION=y
CT_TOOLCHAIN_PKGVERSION=""
CT_TOOLCHAIN_BUGURL=""
@@ -242,207 +216,126 @@ CT_BUILD_SUFFIX=""
# Operating System
#
CT_KERNEL_SUPPORTS_SHARED_LIBS=y
-# CT_KERNEL_BARE_METAL is not set
-CT_KERNEL_LINUX=y
CT_KERNEL="linux"
-CT_KERNEL_CHOICE_KSYM="LINUX"
-CT_KERNEL_LINUX_SHOW=y
-
-#
-# Options for linux
-#
-CT_KERNEL_LINUX_PKG_KSYM="LINUX"
-CT_LINUX_DIR_NAME="linux"
-CT_LINUX_PKG_NAME="linux"
-CT_LINUX_SRC_RELEASE=y
-CT_LINUX_PATCH_ORDER="global"
-# CT_LINUX_V_4_20 is not set
-# CT_LINUX_V_4_19 is not set
-# CT_LINUX_V_4_18 is not set
-# CT_LINUX_V_4_17 is not set
-# CT_LINUX_V_4_16 is not set
-# CT_LINUX_V_4_15 is not set
-# CT_LINUX_V_4_14 is not set
-# CT_LINUX_V_4_13 is not set
-# CT_LINUX_V_4_12 is not set
-# CT_LINUX_V_4_11 is not set
-# CT_LINUX_V_4_10 is not set
-# CT_LINUX_V_4_9 is not set
-# CT_LINUX_V_4_4 is not set
-# CT_LINUX_V_4_1 is not set
-# CT_LINUX_V_3_16 is not set
-# CT_LINUX_V_3_13 is not set
-# CT_LINUX_V_3_12 is not set
-# CT_LINUX_V_3_10 is not set
-# CT_LINUX_V_3_4 is not set
-CT_LINUX_V_3_2=y
-# CT_LINUX_V_2_6_32 is not set
-# CT_LINUX_NO_VERSIONS is not set
-CT_LINUX_VERSION="3.2.101"
-CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})"
-CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
-CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
-CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz"
-CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign"
-CT_LINUX_4_8_or_older=y
-CT_LINUX_older_than_4_8=y
-CT_LINUX_3_7_or_older=y
-CT_LINUX_older_than_3_7=y
-CT_LINUX_later_than_3_2=y
-CT_LINUX_3_2_or_later=y
-CT_KERNEL_LINUX_VERBOSITY_0=y
-# CT_KERNEL_LINUX_VERBOSITY_1 is not set
-# CT_KERNEL_LINUX_VERBOSITY_2 is not set
-CT_KERNEL_LINUX_VERBOSE_LEVEL=0
-CT_KERNEL_LINUX_INSTALL_CHECK=y
-CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS"
+CT_KERNEL_VERSION="3.2.72"
+# CT_KERNEL_bare_metal is not set
+CT_KERNEL_linux=y
+CT_KERNEL_bare_metal_AVAILABLE=y
+CT_KERNEL_linux_AVAILABLE=y
+# CT_KERNEL_V_4_3 is not set
+# CT_KERNEL_V_4_2 is not set
+# CT_KERNEL_V_4_1 is not set
+# CT_KERNEL_V_3_18 is not set
+# CT_KERNEL_V_3_14 is not set
+# CT_KERNEL_V_3_12 is not set
+# CT_KERNEL_V_3_10 is not set
+# CT_KERNEL_V_3_4 is not set
+CT_KERNEL_V_3_2=y
+# CT_KERNEL_V_2_6_32 is not set
+# CT_KERNEL_LINUX_CUSTOM is not set
+CT_KERNEL_windows_AVAILABLE=y
#
# Common kernel options
#
CT_SHARED_LIBS=y
+#
+# linux other options
+#
+CT_KERNEL_LINUX_VERBOSITY_0=y
+# CT_KERNEL_LINUX_VERBOSITY_1 is not set
+# CT_KERNEL_LINUX_VERBOSITY_2 is not set
+CT_KERNEL_LINUX_VERBOSE_LEVEL=0
+CT_KERNEL_LINUX_INSTALL_CHECK=y
+
#
# Binary utilities
#
CT_ARCH_BINFMT_ELF=y
-CT_BINUTILS_BINUTILS=y
CT_BINUTILS="binutils"
-CT_BINUTILS_CHOICE_KSYM="BINUTILS"
-CT_BINUTILS_BINUTILS_SHOW=y
-
-#
-# Options for binutils
-#
-CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS"
-CT_BINUTILS_DIR_NAME="binutils"
-CT_BINUTILS_USE_GNU=y
-CT_BINUTILS_USE="BINUTILS"
-CT_BINUTILS_PKG_NAME="binutils"
-CT_BINUTILS_SRC_RELEASE=y
-CT_BINUTILS_PATCH_ORDER="global"
-CT_BINUTILS_V_2_32=y
-# CT_BINUTILS_V_2_31 is not set
-# CT_BINUTILS_V_2_30 is not set
-# CT_BINUTILS_V_2_29 is not set
-# CT_BINUTILS_V_2_28 is not set
-# CT_BINUTILS_V_2_27 is not set
-# CT_BINUTILS_V_2_26 is not set
-# CT_BINUTILS_NO_VERSIONS is not set
-CT_BINUTILS_VERSION="2.32"
-CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)"
-CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
-CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
-CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
-CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig"
-CT_BINUTILS_later_than_2_30=y
-CT_BINUTILS_2_30_or_later=y
-CT_BINUTILS_later_than_2_27=y
-CT_BINUTILS_2_27_or_later=y
-CT_BINUTILS_later_than_2_25=y
-CT_BINUTILS_2_25_or_later=y
-CT_BINUTILS_later_than_2_23=y
-CT_BINUTILS_2_23_or_later=y
+CT_BINUTILS_binutils=y
#
# GNU binutils
#
+# CT_CC_BINUTILS_SHOW_LINARO is not set
+CT_BINUTILS_V_2_25_1=y
+# CT_BINUTILS_V_2_25 is not set
+# CT_BINUTILS_V_2_24 is not set
+# CT_BINUTILS_V_2_23_2 is not set
+# CT_BINUTILS_V_2_23_1 is not set
+# CT_BINUTILS_V_2_22 is not set
+# CT_BINUTILS_V_2_21_53 is not set
+# CT_BINUTILS_V_2_21_1a is not set
+# CT_BINUTILS_V_2_20_1a is not set
+# CT_BINUTILS_V_2_19_1a is not set
+# CT_BINUTILS_V_2_18a is not set
+CT_BINUTILS_VERSION="2.25.1"
+CT_BINUTILS_2_25_1_or_later=y
+CT_BINUTILS_2_25_or_later=y
+CT_BINUTILS_2_24_or_later=y
+CT_BINUTILS_2_23_or_later=y
+CT_BINUTILS_2_22_or_later=y
+CT_BINUTILS_2_21_or_later=y
+CT_BINUTILS_2_20_or_later=y
+CT_BINUTILS_2_19_or_later=y
+CT_BINUTILS_2_18_or_later=y
CT_BINUTILS_HAS_HASH_STYLE=y
CT_BINUTILS_HAS_GOLD=y
-CT_BINUTILS_HAS_PLUGINS=y
-CT_BINUTILS_HAS_PKGVERSION_BUGURL=y
CT_BINUTILS_GOLD_SUPPORTS_ARCH=y
CT_BINUTILS_GOLD_SUPPORT=y
-CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y
+CT_BINUTILS_HAS_PLUGINS=y
+CT_BINUTILS_HAS_PKGVERSION_BUGURL=y
+CT_BINUTILS_FORCE_LD_BFD=y
CT_BINUTILS_LINKER_LD=y
# CT_BINUTILS_LINKER_LD_GOLD is not set
+# CT_BINUTILS_LINKER_GOLD_LD is not set
CT_BINUTILS_LINKERS_LIST="ld"
CT_BINUTILS_LINKER_DEFAULT="bfd"
# CT_BINUTILS_PLUGINS is not set
-CT_BINUTILS_RELRO=m
CT_BINUTILS_EXTRA_CONFIG_ARRAY=""
# CT_BINUTILS_FOR_TARGET is not set
-CT_ALL_BINUTILS_CHOICES="BINUTILS"
+
+#
+# binutils other options
+#
#
# C-library
#
-CT_LIBC_GLIBC=y
-# CT_LIBC_UCLIBC is not set
CT_LIBC="glibc"
-CT_LIBC_CHOICE_KSYM="GLIBC"
+CT_LIBC_VERSION="2.16.0"
+CT_LIBC_glibc=y
+# CT_LIBC_musl is not set
+# CT_LIBC_uClibc is not set
+CT_LIBC_avr_libc_AVAILABLE=y
+CT_LIBC_glibc_AVAILABLE=y
CT_THREADS="nptl"
-CT_LIBC_GLIBC_SHOW=y
-
-#
-# Options for glibc
-#
-CT_LIBC_GLIBC_PKG_KSYM="GLIBC"
-CT_GLIBC_DIR_NAME="glibc"
-CT_GLIBC_USE_GNU=y
-CT_GLIBC_USE="GLIBC"
-CT_GLIBC_PKG_NAME="glibc"
-CT_GLIBC_SRC_RELEASE=y
-CT_GLIBC_PATCH_ORDER="global"
-# CT_GLIBC_V_2_29 is not set
-# CT_GLIBC_V_2_28 is not set
-# CT_GLIBC_V_2_27 is not set
-# CT_GLIBC_V_2_26 is not set
-# CT_GLIBC_V_2_25 is not set
-# CT_GLIBC_V_2_24 is not set
-# CT_GLIBC_V_2_23 is not set
-# CT_GLIBC_V_2_19 is not set
-CT_GLIBC_V_2_17=y
-# CT_GLIBC_V_2_12_1 is not set
-# CT_GLIBC_NO_VERSIONS is not set
-CT_GLIBC_VERSION="2.17"
-CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)"
-CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
-CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
-CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
-CT_GLIBC_SIGNATURE_FORMAT="packed/.sig"
-CT_GLIBC_2_29_or_older=y
-CT_GLIBC_older_than_2_29=y
-CT_GLIBC_2_27_or_older=y
-CT_GLIBC_older_than_2_27=y
-CT_GLIBC_2_26_or_older=y
-CT_GLIBC_older_than_2_26=y
-CT_GLIBC_2_25_or_older=y
-CT_GLIBC_older_than_2_25=y
-CT_GLIBC_2_24_or_older=y
-CT_GLIBC_older_than_2_24=y
-CT_GLIBC_2_23_or_older=y
-CT_GLIBC_older_than_2_23=y
-CT_GLIBC_2_20_or_older=y
-CT_GLIBC_older_than_2_20=y
-CT_GLIBC_2_17_or_later=y
-CT_GLIBC_2_17_or_older=y
-CT_GLIBC_later_than_2_14=y
-CT_GLIBC_2_14_or_later=y
-CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y
-CT_GLIBC_DEP_BINUTILS=y
-CT_GLIBC_DEP_GCC=y
-CT_GLIBC_DEP_PYTHON=y
-CT_GLIBC_HAS_NPTL_ADDON=y
-CT_GLIBC_HAS_PORTS_ADDON=y
-CT_GLIBC_HAS_LIBIDN_ADDON=y
-CT_GLIBC_USE_PORTS_ADDON=y
-CT_GLIBC_USE_NPTL_ADDON=y
-# CT_GLIBC_USE_LIBIDN_ADDON is not set
-CT_GLIBC_HAS_OBSOLETE_RPC=y
-CT_GLIBC_EXTRA_CONFIG_ARRAY=""
-CT_GLIBC_CONFIGPARMS=""
-CT_GLIBC_EXTRA_CFLAGS=""
-CT_GLIBC_ENABLE_OBSOLETE_RPC=y
-# CT_GLIBC_DISABLE_VERSIONING is not set
-CT_GLIBC_OLDEST_ABI=""
-CT_GLIBC_FORCE_UNWIND=y
-# CT_GLIBC_LOCALES is not set
-# CT_GLIBC_KERNEL_VERSION_NONE is not set
-CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y
-# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set
-CT_GLIBC_MIN_KERNEL="3.2.101"
-CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC"
+# CT_CC_GLIBC_SHOW_LINARO is not set
+# CT_LIBC_GLIBC_V_2_22 is not set
+# CT_LIBC_GLIBC_V_2_21 is not set
+# CT_LIBC_GLIBC_V_2_20 is not set
+# CT_LIBC_GLIBC_V_2_19 is not set
+# CT_LIBC_GLIBC_V_2_18 is not set
+# CT_LIBC_GLIBC_V_2_17 is not set
+CT_LIBC_GLIBC_V_2_16_0=y
+# CT_LIBC_GLIBC_V_2_15 is not set
+# CT_LIBC_GLIBC_V_2_14_1 is not set
+# CT_LIBC_GLIBC_V_2_14 is not set
+# CT_LIBC_GLIBC_V_2_13 is not set
+# CT_LIBC_GLIBC_V_2_12_2 is not set
+# CT_LIBC_GLIBC_V_2_12_1 is not set
+# CT_LIBC_GLIBC_V_2_11_1 is not set
+# CT_LIBC_GLIBC_V_2_11 is not set
+# CT_LIBC_GLIBC_V_2_10_1 is not set
+# CT_LIBC_GLIBC_V_2_9 is not set
+# CT_LIBC_GLIBC_V_2_8 is not set
+CT_LIBC_mingw_AVAILABLE=y
+CT_LIBC_musl_AVAILABLE=y
+CT_LIBC_newlib_AVAILABLE=y
+CT_LIBC_none_AVAILABLE=y
+CT_LIBC_uClibc_AVAILABLE=y
CT_LIBC_SUPPORT_THREADS_ANY=y
CT_LIBC_SUPPORT_THREADS_NATIVE=y
@@ -450,71 +343,100 @@ CT_LIBC_SUPPORT_THREADS_NATIVE=y
# Common C library options
#
CT_THREADS_NATIVE=y
-# CT_CREATE_LDSO_CONF is not set
CT_LIBC_XLDD=y
+#
+# glibc other options
+#
+CT_LIBC_GLIBC_PORTS_EXTERNAL=y
+CT_LIBC_GLIBC_MAY_FORCE_PORTS=y
+CT_LIBC_glibc_familly=y
+CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY=""
+CT_LIBC_GLIBC_CONFIGPARMS=""
+CT_LIBC_GLIBC_EXTRA_CFLAGS=""
+CT_LIBC_EXTRA_CC_ARGS=""
+# CT_LIBC_DISABLE_VERSIONING is not set
+CT_LIBC_OLDEST_ABI=""
+CT_LIBC_GLIBC_FORCE_UNWIND=y
+CT_LIBC_GLIBC_USE_PORTS=y
+CT_LIBC_ADDONS_LIST=""
+
+#
+# WARNING !!!
+#
+
+#
+# For glibc >= 2.8, it can happen that the tarballs
+#
+
+#
+# for the addons are not available for download.
+#
+
+#
+# If that happens, bad luck... Try a previous version
+#
+
+#
+# or try again later... :-(
+#
+# CT_LIBC_LOCALES is not set
+# CT_LIBC_GLIBC_KERNEL_VERSION_NONE is not set
+CT_LIBC_GLIBC_KERNEL_VERSION_AS_HEADERS=y
+# CT_LIBC_GLIBC_KERNEL_VERSION_CHOSEN is not set
+CT_LIBC_GLIBC_MIN_KERNEL="3.2.72"
+
#
# C compiler
#
+CT_CC="gcc"
CT_CC_CORE_PASSES_NEEDED=y
CT_CC_CORE_PASS_1_NEEDED=y
CT_CC_CORE_PASS_2_NEEDED=y
-CT_CC_SUPPORT_CXX=y
-CT_CC_SUPPORT_FORTRAN=y
-CT_CC_SUPPORT_ADA=y
-CT_CC_SUPPORT_OBJC=y
-CT_CC_SUPPORT_OBJCXX=y
-CT_CC_SUPPORT_GOLANG=y
-CT_CC_GCC=y
-CT_CC="gcc"
-CT_CC_CHOICE_KSYM="GCC"
-CT_CC_GCC_SHOW=y
-
-#
-# Options for gcc
-#
-CT_CC_GCC_PKG_KSYM="GCC"
-CT_GCC_DIR_NAME="gcc"
-CT_GCC_USE_GNU=y
-CT_GCC_USE="GCC"
-CT_GCC_PKG_NAME="gcc"
-CT_GCC_SRC_RELEASE=y
-CT_GCC_PATCH_ORDER="global"
-CT_GCC_V_8=y
-# CT_GCC_V_7 is not set
-# CT_GCC_V_6 is not set
-# CT_GCC_V_5 is not set
-# CT_GCC_V_4_9 is not set
-# CT_GCC_NO_VERSIONS is not set
-CT_GCC_VERSION="8.3.0"
-CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})"
-CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
-CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
-CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz"
-CT_GCC_SIGNATURE_FORMAT=""
-CT_GCC_later_than_7=y
-CT_GCC_7_or_later=y
-CT_GCC_later_than_6=y
-CT_GCC_6_or_later=y
-CT_GCC_later_than_5=y
-CT_GCC_5_or_later=y
-CT_GCC_later_than_4_9=y
-CT_GCC_4_9_or_later=y
-CT_GCC_later_than_4_8=y
-CT_GCC_4_8_or_later=y
-CT_CC_GCC_HAS_LIBMPX=y
+CT_CC_gcc=y
+# CT_CC_GCC_SHOW_LINARO is not set
+CT_CC_GCC_V_5_2_0=y
+# CT_CC_GCC_V_4_9_3 is not set
+# CT_CC_GCC_V_4_8_5 is not set
+# CT_CC_GCC_V_4_7_4 is not set
+# CT_CC_GCC_V_4_6_4 is not set
+# CT_CC_GCC_V_4_5_4 is not set
+# CT_CC_GCC_V_4_4_7 is not set
+# CT_CC_GCC_V_4_3_6 is not set
+# CT_CC_GCC_V_4_2_4 is not set
+CT_CC_GCC_4_2_or_later=y
+CT_CC_GCC_4_3_or_later=y
+CT_CC_GCC_4_4_or_later=y
+CT_CC_GCC_4_5_or_later=y
+CT_CC_GCC_4_6_or_later=y
+CT_CC_GCC_4_7_or_later=y
+CT_CC_GCC_4_8_or_later=y
+CT_CC_GCC_4_9_or_later=y
+CT_CC_GCC_5=y
+CT_CC_GCC_5_or_later=y
+CT_CC_GCC_HAS_GRAPHITE=y
+CT_CC_GCC_USE_GRAPHITE=y
+CT_CC_GCC_HAS_LTO=y
+CT_CC_GCC_USE_LTO=y
+CT_CC_GCC_HAS_PKGVERSION_BUGURL=y
+CT_CC_GCC_HAS_BUILD_ID=y
+CT_CC_GCC_HAS_LNK_HASH_STYLE=y
+CT_CC_GCC_USE_GMP_MPFR=y
+CT_CC_GCC_USE_MPC=y
+CT_CC_GCC_HAS_LIBQUADMATH=y
+CT_CC_GCC_HAS_LIBSANITIZER=y
+CT_CC_GCC_VERSION="5.2.0"
+# CT_CC_LANG_FORTRAN is not set
CT_CC_GCC_ENABLE_CXX_FLAGS=""
CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY=""
CT_CC_GCC_EXTRA_CONFIG_ARRAY=""
+CT_CC_GCC_EXTRA_ENV_ARRAY=""
CT_CC_GCC_STATIC_LIBSTDCXX=y
# CT_CC_GCC_SYSTEM_ZLIB is not set
-CT_CC_GCC_CONFIG_TLS=m
#
# Optimisation features
#
-CT_CC_GCC_USE_GRAPHITE=y
-CT_CC_GCC_USE_LTO=y
#
# Settings for libraries running on target
@@ -543,206 +465,97 @@ CT_CC_GCC_DEC_FLOAT_AUTO=y
# CT_CC_GCC_DEC_FLOAT_BID is not set
# CT_CC_GCC_DEC_FLOAT_DPD is not set
# CT_CC_GCC_DEC_FLOATS_NO is not set
-CT_ALL_CC_CHOICES="GCC"
+CT_CC_SUPPORT_CXX=y
+CT_CC_SUPPORT_FORTRAN=y
+CT_CC_SUPPORT_JAVA=y
+CT_CC_SUPPORT_ADA=y
+CT_CC_SUPPORT_OBJC=y
+CT_CC_SUPPORT_OBJCXX=y
+CT_CC_SUPPORT_GOLANG=y
#
# Additional supported languages:
#
CT_CC_LANG_CXX=y
-# CT_CC_LANG_FORTRAN is not set
+# CT_CC_LANG_JAVA is not set
#
# Debug facilities
#
-# CT_DEBUG_DUMA is not set
-# CT_DEBUG_GDB is not set
-# CT_DEBUG_LTRACE is not set
-# CT_DEBUG_STRACE is not set
-CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE"
+# CT_DEBUG_dmalloc is not set
+# CT_DEBUG_duma is not set
+# CT_DEBUG_gdb is not set
+# CT_DEBUG_ltrace is not set
+# CT_DEBUG_strace is not set
#
# Companion libraries
#
-# CT_COMPLIBS_CHECK is not set
-# CT_COMP_LIBS_CLOOG is not set
-# CT_COMP_LIBS_EXPAT is not set
-CT_COMP_LIBS_GETTEXT=y
-CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT"
-CT_GETTEXT_DIR_NAME="gettext"
-CT_GETTEXT_PKG_NAME="gettext"
-CT_GETTEXT_SRC_RELEASE=y
-CT_GETTEXT_PATCH_ORDER="global"
-CT_GETTEXT_V_0_19_8_1=y
-# CT_GETTEXT_NO_VERSIONS is not set
-CT_GETTEXT_VERSION="0.19.8.1"
-CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)"
-CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
-CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
-CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz"
-CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig"
-CT_COMP_LIBS_GMP=y
-CT_COMP_LIBS_GMP_PKG_KSYM="GMP"
-CT_GMP_DIR_NAME="gmp"
-CT_GMP_PKG_NAME="gmp"
-CT_GMP_SRC_RELEASE=y
-CT_GMP_PATCH_ORDER="global"
-CT_GMP_V_6_1=y
-# CT_GMP_NO_VERSIONS is not set
-CT_GMP_VERSION="6.1.2"
-CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)"
-CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
-CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
-CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2"
-CT_GMP_SIGNATURE_FORMAT="packed/.sig"
-CT_GMP_later_than_5_1_0=y
-CT_GMP_5_1_0_or_later=y
-CT_GMP_later_than_5_0_0=y
-CT_GMP_5_0_0_or_later=y
-CT_COMP_LIBS_ISL=y
-CT_COMP_LIBS_ISL_PKG_KSYM="ISL"
-CT_ISL_DIR_NAME="isl"
-CT_ISL_PKG_NAME="isl"
-CT_ISL_SRC_RELEASE=y
-CT_ISL_PATCH_ORDER="global"
-CT_ISL_V_0_20=y
-# CT_ISL_V_0_19 is not set
-# CT_ISL_V_0_18 is not set
-# CT_ISL_V_0_17 is not set
-# CT_ISL_V_0_16 is not set
-# CT_ISL_V_0_15 is not set
-# CT_ISL_NO_VERSIONS is not set
-CT_ISL_VERSION="0.20"
-CT_ISL_MIRRORS="http://isl.gforge.inria.fr"
-CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
-CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
-CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
-CT_ISL_SIGNATURE_FORMAT=""
-CT_ISL_later_than_0_18=y
-CT_ISL_0_18_or_later=y
-CT_ISL_later_than_0_15=y
-CT_ISL_0_15_or_later=y
-CT_ISL_REQUIRE_0_15_or_later=y
-CT_ISL_later_than_0_14=y
-CT_ISL_0_14_or_later=y
-CT_ISL_REQUIRE_0_14_or_later=y
-CT_ISL_later_than_0_13=y
-CT_ISL_0_13_or_later=y
-CT_ISL_later_than_0_12=y
-CT_ISL_0_12_or_later=y
-CT_ISL_REQUIRE_0_12_or_later=y
-# CT_COMP_LIBS_LIBELF is not set
-CT_COMP_LIBS_LIBICONV=y
-CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV"
-CT_LIBICONV_DIR_NAME="libiconv"
-CT_LIBICONV_PKG_NAME="libiconv"
-CT_LIBICONV_SRC_RELEASE=y
-CT_LIBICONV_PATCH_ORDER="global"
-CT_LIBICONV_V_1_15=y
-# CT_LIBICONV_NO_VERSIONS is not set
-CT_LIBICONV_VERSION="1.15"
-CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)"
-CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
-CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
-CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz"
-CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig"
-CT_COMP_LIBS_MPC=y
-CT_COMP_LIBS_MPC_PKG_KSYM="MPC"
-CT_MPC_DIR_NAME="mpc"
-CT_MPC_PKG_NAME="mpc"
-CT_MPC_SRC_RELEASE=y
-CT_MPC_PATCH_ORDER="global"
-# CT_MPC_V_1_1 is not set
-CT_MPC_V_1_0=y
-# CT_MPC_NO_VERSIONS is not set
-CT_MPC_VERSION="1.0.3"
-CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)"
-CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
-CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
-CT_MPC_ARCHIVE_FORMATS=".tar.gz"
-CT_MPC_SIGNATURE_FORMAT="packed/.sig"
-CT_MPC_1_1_0_or_older=y
-CT_MPC_older_than_1_1_0=y
-CT_COMP_LIBS_MPFR=y
-CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR"
-CT_MPFR_DIR_NAME="mpfr"
-CT_MPFR_PKG_NAME="mpfr"
-CT_MPFR_SRC_RELEASE=y
-CT_MPFR_PATCH_ORDER="global"
-CT_MPFR_V_3_1=y
-# CT_MPFR_NO_VERSIONS is not set
-CT_MPFR_VERSION="3.1.6"
-CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)"
-CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
-CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
-CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip"
-CT_MPFR_SIGNATURE_FORMAT="packed/.asc"
-CT_MPFR_4_0_0_or_older=y
-CT_MPFR_older_than_4_0_0=y
-CT_MPFR_REQUIRE_older_than_4_0_0=y
-CT_MPFR_later_than_3_0_0=y
-CT_MPFR_3_0_0_or_later=y
-CT_COMP_LIBS_NCURSES=y
-CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES"
-CT_NCURSES_DIR_NAME="ncurses"
-CT_NCURSES_PKG_NAME="ncurses"
-CT_NCURSES_SRC_RELEASE=y
-CT_NCURSES_PATCH_ORDER="global"
-CT_NCURSES_V_6_1=y
-# CT_NCURSES_V_6_0 is not set
-# CT_NCURSES_NO_VERSIONS is not set
-CT_NCURSES_VERSION="6.1"
-CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)"
-CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
-CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
-CT_NCURSES_ARCHIVE_FORMATS=".tar.gz"
-CT_NCURSES_SIGNATURE_FORMAT="packed/.sig"
-CT_NCURSES_HOST_CONFIG_ARGS=""
-CT_NCURSES_HOST_DISABLE_DB=y
-CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100"
-CT_NCURSES_TARGET_CONFIG_ARGS=""
-# CT_NCURSES_TARGET_DISABLE_DB is not set
-CT_NCURSES_TARGET_FALLBACKS=""
-CT_COMP_LIBS_ZLIB=y
-CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB"
-CT_ZLIB_DIR_NAME="zlib"
-CT_ZLIB_PKG_NAME="zlib"
-CT_ZLIB_SRC_RELEASE=y
-CT_ZLIB_PATCH_ORDER="global"
-CT_ZLIB_V_1_2_11=y
-# CT_ZLIB_NO_VERSIONS is not set
-CT_ZLIB_VERSION="1.2.11"
-CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}"
-CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
-CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
-CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz"
-CT_ZLIB_SIGNATURE_FORMAT="packed/.asc"
-CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB"
+CT_COMPLIBS_NEEDED=y
CT_LIBICONV_NEEDED=y
CT_GETTEXT_NEEDED=y
CT_GMP_NEEDED=y
CT_MPFR_NEEDED=y
CT_ISL_NEEDED=y
CT_MPC_NEEDED=y
-CT_NCURSES_NEEDED=y
-CT_ZLIB_NEEDED=y
+CT_COMPLIBS=y
CT_LIBICONV=y
CT_GETTEXT=y
CT_GMP=y
CT_MPFR=y
CT_ISL=y
CT_MPC=y
-CT_NCURSES=y
-CT_ZLIB=y
+CT_LIBICONV_V_1_14=y
+CT_LIBICONV_VERSION="1.14"
+CT_GETTEXT_V_0_19_6=y
+CT_GETTEXT_VERSION="0.19.6"
+CT_GMP_V_6_0_0=y
+# CT_GMP_V_5_1_3 is not set
+# CT_GMP_V_5_1_1 is not set
+# CT_GMP_V_5_0_2 is not set
+# CT_GMP_V_5_0_1 is not set
+# CT_GMP_V_4_3_2 is not set
+# CT_GMP_V_4_3_1 is not set
+# CT_GMP_V_4_3_0 is not set
+CT_GMP_5_0_2_or_later=y
+CT_GMP_VERSION="6.0.0a"
+CT_MPFR_V_3_1_3=y
+# CT_MPFR_V_3_1_2 is not set
+# CT_MPFR_V_3_1_0 is not set
+# CT_MPFR_V_3_0_1 is not set
+# CT_MPFR_V_3_0_0 is not set
+# CT_MPFR_V_2_4_2 is not set
+# CT_MPFR_V_2_4_1 is not set
+# CT_MPFR_V_2_4_0 is not set
+CT_MPFR_VERSION="3.1.3"
+CT_ISL_V_0_14=y
+# CT_ISL_V_0_12_2 is not set
+CT_ISL_V_0_14_or_later=y
+CT_ISL_V_0_12_or_later=y
+CT_ISL_VERSION="0.14"
+# CT_CLOOG_V_0_18_4 is not set
+# CT_CLOOG_V_0_18_1 is not set
+# CT_CLOOG_V_0_18_0 is not set
+CT_MPC_V_1_0_3=y
+# CT_MPC_V_1_0_2 is not set
+# CT_MPC_V_1_0_1 is not set
+# CT_MPC_V_1_0 is not set
+# CT_MPC_V_0_9 is not set
+# CT_MPC_V_0_8_2 is not set
+# CT_MPC_V_0_8_1 is not set
+# CT_MPC_V_0_7 is not set
+CT_MPC_VERSION="1.0.3"
+
+#
+# Companion libraries common options
+#
+# CT_COMPLIBS_CHECK is not set
#
# Companion tools
#
-# CT_COMP_TOOLS_FOR_HOST is not set
-# CT_COMP_TOOLS_AUTOCONF is not set
-# CT_COMP_TOOLS_AUTOMAKE is not set
-# CT_COMP_TOOLS_BISON is not set
-# CT_COMP_TOOLS_DTC is not set
-# CT_COMP_TOOLS_LIBTOOL is not set
-# CT_COMP_TOOLS_M4 is not set
-# CT_COMP_TOOLS_MAKE is not set
-CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE"
+
+#
+# READ HELP before you say 'Y' below !!!
+#
+# CT_COMP_TOOLS is not set
diff --git a/src/ci/docker/dist-armv7-linux/crosstool-ng.sh b/src/ci/docker/dist-armv7-linux/crosstool-ng.sh
deleted file mode 100644
index ae737d9677d87..0000000000000
--- a/src/ci/docker/dist-armv7-linux/crosstool-ng.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-set -ex
-
-# Mirrored from https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-1.24.0.tar.gz
-url="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/crosstool-ng-1.24.0.tar.gz"
-curl -Lf $url | tar xzf -
-cd crosstool-ng-crosstool-ng-1.24.0
-./bootstrap
-./configure --prefix=/usr/local
-make -j$(nproc)
-make install
-cd ..
-rm -rf crosstool-ng-crosstool-ng-1.24.0
diff --git a/src/ci/docker/dist-armv7-linux/patches/glibc/ports-2.16.0/001-arm-libgcc_s_resume-used.patch b/src/ci/docker/dist-armv7-linux/patches/glibc/ports-2.16.0/001-arm-libgcc_s_resume-used.patch
new file mode 100644
index 0000000000000..871d5225c0f71
--- /dev/null
+++ b/src/ci/docker/dist-armv7-linux/patches/glibc/ports-2.16.0/001-arm-libgcc_s_resume-used.patch
@@ -0,0 +1,48 @@
+commit bdb24c2851fd5f0ad9b82d7ea1db911d334b02d2
+Author: Joseph Myers
+Date: Tue May 20 21:27:13 2014 +0000
+
+ Fix ARM build with GCC trunk.
+
+ sysdeps/unix/sysv/linux/arm/unwind-resume.c and
+ sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c have static
+ variables that are written in C code but only read from toplevel asms.
+ Current GCC trunk now optimizes away such apparently write-only static
+ variables, so causing a build failure. This patch marks those
+ variables with __attribute_used__ to avoid that optimization.
+
+ Tested that this fixes the build for ARM.
+
+ * sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c
+ (libgcc_s_resume): Use __attribute_used__.
+ * sysdeps/unix/sysv/linux/arm/unwind-resume.c (libgcc_s_resume):
+ Likewise.
+
+diff --git a/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c b/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
+index 29e2c2b00b04..e848bfeffdcb 100644
+--- a/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
++++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
+@@ -22,7 +22,8 @@
+ #include
+
+ static void *libgcc_s_handle;
+-static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
++static void (*libgcc_s_resume) (struct _Unwind_Exception *exc)
++ __attribute_used__;
+ static _Unwind_Reason_Code (*libgcc_s_personality)
+ (_Unwind_State, struct _Unwind_Exception *, struct _Unwind_Context *);
+ static _Unwind_Reason_Code (*libgcc_s_forcedunwind)
+diff --git a/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c b/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c
+index 285b99b5ed0d..48d00fc83641 100644
+--- a/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c
++++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c
+@@ -20,7 +20,8 @@
+ #include
+ #include
+
+-static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
++static void (*libgcc_s_resume) (struct _Unwind_Exception *exc)
++ __attribute_used__;
+ static _Unwind_Reason_Code (*libgcc_s_personality)
+ (_Unwind_State, struct _Unwind_Exception *, struct _Unwind_Context *);
+
diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile
index fab3824a20ae3..105791194628b 100644
--- a/src/ci/docker/dist-various-1/Dockerfile
+++ b/src/ci/docker/dist-various-1/Dockerfile
@@ -139,6 +139,7 @@ ENV RUST_CONFIGURE_ARGS \
--musl-root-aarch64=/musl-aarch64 \
--musl-root-mips=/musl-mips \
--musl-root-mipsel=/musl-mipsel \
+ --enable-emscripten \
--disable-docs
ENV SCRIPT \
diff --git a/src/ci/docker/dist-x86_64-linux/build-curl.sh b/src/ci/docker/dist-x86_64-linux/build-curl.sh
index 8200bbe2fdce5..fb8b63d7920b1 100755
--- a/src/ci/docker/dist-x86_64-linux/build-curl.sh
+++ b/src/ci/docker/dist-x86_64-linux/build-curl.sh
@@ -3,11 +3,9 @@
set -ex
source shared.sh
-VERSION=7.66.0
+VERSION=7.51.0
-curl https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/curl-$VERSION.tar.xz \
- | xz --decompress \
- | tar xf -
+curl http://cool.haxx.se/download/curl-$VERSION.tar.bz2 | tar xjf -
mkdir curl-build
cd curl-build
diff --git a/src/ci/docker/scripts/cross-apt-packages.sh b/src/ci/docker/scripts/cross-apt-packages.sh
index bb72e33def21c..51945fd72adc7 100644
--- a/src/ci/docker/scripts/cross-apt-packages.sh
+++ b/src/ci/docker/scripts/cross-apt-packages.sh
@@ -22,6 +22,5 @@ apt-get update && apt-get install -y --no-install-recommends \
python2.7 \
sudo \
texinfo \
- unzip \
wget \
xz-utils
diff --git a/src/ci/docker/scripts/emscripten-wasm.sh b/src/ci/docker/scripts/emscripten-wasm.sh
new file mode 100644
index 0000000000000..e4a93d7a10092
--- /dev/null
+++ b/src/ci/docker/scripts/emscripten-wasm.sh
@@ -0,0 +1,37 @@
+set -ex
+
+hide_output() {
+ set +x
+ on_err="
+echo ERROR: An error was encountered with the build.
+cat /tmp/build.log
+exit 1
+"
+ trap "$on_err" ERR
+ bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
+ PING_LOOP_PID=$!
+ $@ &> /tmp/build.log
+ trap - ERR
+ kill $PING_LOOP_PID
+ rm -f /tmp/build.log
+ set -x
+}
+
+# Download last known good emscripten from WebAssembly waterfall
+BUILD=$(curl -fL https://storage.googleapis.com/wasm-llvm/builds/linux/lkgr.json | \
+ jq '.build | tonumber')
+curl -sL https://storage.googleapis.com/wasm-llvm/builds/linux/$BUILD/wasm-binaries.tbz2 | \
+ hide_output tar xvkj
+
+# node 8 is required to run wasm
+cd /
+curl -sL https://nodejs.org/dist/v8.0.0/node-v8.0.0-linux-x64.tar.xz | \
+ tar -xJ
+
+# Make emscripten use wasm-ready node and LLVM tools
+echo "EMSCRIPTEN_ROOT = '/wasm-install/emscripten'" >> /root/.emscripten
+echo "NODE_JS='/usr/local/bin/node'" >> /root/.emscripten
+echo "LLVM_ROOT='/wasm-install/bin'" >> /root/.emscripten
+echo "BINARYEN_ROOT = '/wasm-install'" >> /root/.emscripten
+echo "COMPILER_ENGINE = NODE_JS" >> /root/.emscripten
+echo "JS_ENGINES = [NODE_JS]" >> /root/.emscripten
diff --git a/src/ci/docker/scripts/emscripten.sh b/src/ci/docker/scripts/emscripten.sh
index 1be80741594cc..47196e8939626 100644
--- a/src/ci/docker/scripts/emscripten.sh
+++ b/src/ci/docker/scripts/emscripten.sh
@@ -17,7 +17,22 @@ exit 1
set -x
}
-git clone https://github.com/emscripten-core/emsdk.git /emsdk-portable
+cd /
+curl -fL https://mozilla-games.s3.amazonaws.com/emscripten/releases/emsdk-portable.tar.gz | \
+ tar -xz
+
cd /emsdk-portable
-hide_output ./emsdk install 1.38.46-upstream
-./emsdk activate 1.38.46-upstream
+./emsdk update
+hide_output ./emsdk install sdk-1.38.15-64bit
+./emsdk activate sdk-1.38.15-64bit
+
+# Compile and cache libc
+source ./emsdk_env.sh
+echo "main(){}" > a.c
+HOME=/emsdk-portable/ emcc a.c
+HOME=/emsdk-portable/ emcc -s BINARYEN=1 a.c
+rm -f a.*
+
+# Make emsdk usable by any user
+cp /root/.emscripten /emsdk-portable
+chmod a+rxw -R /emsdk-portable
diff --git a/src/ci/docker/wasm32/Dockerfile b/src/ci/docker/wasm32/Dockerfile
deleted file mode 100644
index a0f35afd995b3..0000000000000
--- a/src/ci/docker/wasm32/Dockerfile
+++ /dev/null
@@ -1,44 +0,0 @@
-FROM ubuntu:16.04
-
-RUN apt-get update && apt-get install -y --no-install-recommends \
- g++ \
- make \
- file \
- curl \
- ca-certificates \
- python \
- git \
- cmake \
- sudo \
- gdb \
- xz-utils \
- bzip2
-
-COPY scripts/emscripten.sh /scripts/
-RUN bash /scripts/emscripten.sh
-
-COPY scripts/sccache.sh /scripts/
-RUN sh /scripts/sccache.sh
-
-ENV PATH=$PATH:/emsdk-portable
-ENV PATH=$PATH:/emsdk-portable/upstream/emscripten/
-ENV PATH=$PATH:/emsdk-portable/node/12.9.1_64bit/bin/
-ENV BINARYEN_ROOT=/emsdk-portable/upstream/
-
-ENV TARGETS=wasm32-unknown-emscripten
-
-# Use -O1 optimizations in the link step to reduce time spent optimizing.
-ENV EMCC_CFLAGS=-O1
-
-# Emscripten installation is user-specific
-ENV NO_CHANGE_USER=1
-
-# FIXME: Re-enable these tests once https://github.com/rust-lang/cargo/pull/7476
-# is picked up by CI
-ENV SCRIPT python2.7 ../x.py test --target $TARGETS \
- --exclude src/libcore \
- --exclude src/liballoc \
- --exclude src/libproc_macro \
- --exclude src/libstd \
- --exclude src/libterm \
- --exclude src/libtest
diff --git a/src/ci/init_repo.sh b/src/ci/init_repo.sh
index 92c6e546a3895..c7c3b0a5fbf5b 100755
--- a/src/ci/init_repo.sh
+++ b/src/ci/init_repo.sh
@@ -47,7 +47,7 @@ function fetch_github_commit_archive {
rm $cached
}
-included="src/llvm-project src/doc/book src/doc/rust-by-example"
+included="src/llvm-project src/llvm-emscripten src/doc/book src/doc/rust-by-example"
modules="$(git config --file .gitmodules --get-regexp '\.path$' | cut -d' ' -f2)"
modules=($modules)
use_git=""
diff --git a/src/ci/run.sh b/src/ci/run.sh
index 0d5ea371245e4..457ba97171207 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -55,9 +55,6 @@ if [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then
if [ "$NO_LLVM_ASSERTIONS" = "1" ]; then
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions"
elif [ "$DEPLOY_ALT" != "" ]; then
- if [ "$NO_PARALLEL_COMPILER" = "" ]; then
- RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.parallel-compiler"
- fi
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-assertions"
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.verify-llvm-ir"
fi
diff --git a/src/doc/book b/src/doc/book
index 9bb8b161963fc..871416b85c1a7 160000
--- a/src/doc/book
+++ b/src/doc/book
@@ -1 +1 @@
-Subproject commit 9bb8b161963fcebc9d9ccd732ba26f42108016d5
+Subproject commit 871416b85c1a73717d65d6f4a9ea29e5aef3db0e
diff --git a/src/doc/grammar.md b/src/doc/grammar.md
index 4501d74073e90..ee9135b6578f6 100644
--- a/src/doc/grammar.md
+++ b/src/doc/grammar.md
@@ -1,7 +1,812 @@
% Grammar
-The Rust grammar may now be found in the [reference]. Additionally, the [grammar
-working group] is working on producing a testable grammar.
+# Introduction
-[reference]: https://doc.rust-lang.org/reference/
-[grammar working group]: https://github.com/rust-lang/wg-grammar
+This document is the primary reference for the Rust programming language grammar. It
+provides only one kind of material:
+
+ - Chapters that formally define the language grammar.
+
+This document does not serve as an introduction to the language. Background
+familiarity with the language is assumed. A separate [guide] is available to
+help acquire such background.
+
+This document also does not serve as a reference to the [standard] library
+included in the language distribution. Those libraries are documented
+separately by extracting documentation attributes from their source code. Many
+of the features that one might expect to be language features are library
+features in Rust, so what you're looking for may be there, not here.
+
+[guide]: guide.html
+[standard]: std/index.html
+
+# Notation
+
+Rust's grammar is defined over Unicode codepoints, each conventionally denoted
+`U+XXXX`, for 4 or more hexadecimal digits `X`. _Most_ of Rust's grammar is
+confined to the ASCII range of Unicode, and is described in this document by a
+dialect of Extended Backus-Naur Form (EBNF), specifically a dialect of EBNF
+supported by common automated LL(k) parsing tools such as `llgen`, rather than
+the dialect given in ISO 14977. The dialect can be defined self-referentially
+as follows:
+
+```antlr
+grammar : rule + ;
+rule : nonterminal ':' productionrule ';' ;
+productionrule : production [ '|' production ] * ;
+production : term * ;
+term : element repeats ;
+element : LITERAL | IDENTIFIER | '[' productionrule ']' ;
+repeats : [ '*' | '+' ] NUMBER ? | NUMBER ? | '?' ;
+```
+
+Where:
+
+- Whitespace in the grammar is ignored.
+- Square brackets are used to group rules.
+- `LITERAL` is a single printable ASCII character, or an escaped hexadecimal
+ ASCII code of the form `\xQQ`, in single quotes, denoting the corresponding
+ Unicode codepoint `U+00QQ`.
+- `IDENTIFIER` is a nonempty string of ASCII letters and underscores.
+- The `repeat` forms apply to the adjacent `element`, and are as follows:
+ - `?` means zero or one repetition
+ - `*` means zero or more repetitions
+ - `+` means one or more repetitions
+ - NUMBER trailing a repeat symbol gives a maximum repetition count
+ - NUMBER on its own gives an exact repetition count
+
+This EBNF dialect should hopefully be familiar to many readers.
+
+## Unicode productions
+
+A few productions in Rust's grammar permit Unicode codepoints outside the ASCII
+range. We define these productions in terms of character properties specified
+in the Unicode standard, rather than in terms of ASCII-range codepoints. The
+section [Special Unicode Productions](#special-unicode-productions) lists these
+productions.
+
+## String table productions
+
+Some rules in the grammar — notably [unary
+operators](#unary-operator-expressions), [binary
+operators](#binary-operator-expressions), and [keywords](#keywords) — are
+given in a simplified form: as a listing of a table of unquoted, printable
+whitespace-separated strings. These cases form a subset of the rules regarding
+the [token](#tokens) rule, and are assumed to be the result of a
+lexical-analysis phase feeding the parser, driven by a DFA, operating over the
+disjunction of all such string table entries.
+
+When such a string enclosed in double-quotes (`"`) occurs inside the grammar,
+it is an implicit reference to a single member of such a string table
+production. See [tokens](#tokens) for more information.
+
+# Lexical structure
+
+## Input format
+
+Rust input is interpreted as a sequence of Unicode codepoints encoded in UTF-8.
+Most Rust grammar rules are defined in terms of printable ASCII-range
+codepoints, but a small number are defined in terms of Unicode properties or
+explicit codepoint lists. [^inputformat]
+
+[^inputformat]: Substitute definitions for the special Unicode productions are
+ provided to the grammar verifier, restricted to ASCII range, when verifying the
+ grammar in this document.
+
+## Special Unicode Productions
+
+The following productions in the Rust grammar are defined in terms of Unicode
+properties: `ident`, `non_null`, `non_eol`, `non_single_quote` and
+`non_double_quote`.
+
+### Identifiers
+
+The `ident` production is any nonempty Unicode string of
+the following form:
+
+- The first character is in one of the following ranges `U+0041` to `U+005A`
+("A" to "Z"), `U+0061` to `U+007A` ("a" to "z"), or `U+005F` ("\_").
+- The remaining characters are in the range `U+0030` to `U+0039` ("0" to "9"),
+or any of the prior valid initial characters.
+
+as long as the identifier does _not_ occur in the set of [keywords](#keywords).
+
+### Delimiter-restricted productions
+
+Some productions are defined by exclusion of particular Unicode characters:
+
+- `non_null` is any single Unicode character aside from `U+0000` (null)
+- `non_eol` is any single Unicode character aside from `U+000A` (`'\n'`)
+- `non_single_quote` is any single Unicode character aside from `U+0027` (`'`)
+- `non_double_quote` is any single Unicode character aside from `U+0022` (`"`)
+
+## Comments
+
+```antlr
+comment : block_comment | line_comment ;
+block_comment : "/*" block_comment_body * "*/" ;
+block_comment_body : [block_comment | character] * ;
+line_comment : "//" non_eol * ;
+```
+
+**FIXME:** add doc grammar?
+
+## Whitespace
+
+```antlr
+whitespace_char : '\x20' | '\x09' | '\x0a' | '\x0d' ;
+whitespace : [ whitespace_char | comment ] + ;
+```
+
+## Tokens
+
+```antlr
+simple_token : keyword | unop | binop ;
+token : simple_token | ident | literal | symbol | whitespace token ;
+```
+
+### Keywords
+
+
+
+| | | | | |
+|----------|----------|----------|----------|----------|
+| _ | abstract | alignof | as | become |
+| box | break | const | continue | crate |
+| do | else | enum | extern | false |
+| final | fn | for | if | impl |
+| in | let | loop | macro | match |
+| mod | move | mut | offsetof | override |
+| priv | proc | pub | pure | ref |
+| return | Self | self | sizeof | static |
+| struct | super | trait | true | type |
+| typeof | unsafe | unsized | use | virtual |
+| where | while | yield | | |
+
+
+Each of these keywords has special meaning in its grammar, and all of them are
+excluded from the `ident` rule.
+
+Not all of these keywords are used by the language. Some of them were used
+before Rust 1.0, and were left reserved once their implementations were
+removed. Some of them were reserved before 1.0 to make space for possible
+future features.
+
+### Literals
+
+```antlr
+lit_suffix : ident;
+literal : [ string_lit | char_lit | byte_string_lit | byte_lit | num_lit | bool_lit ] lit_suffix ?;
+```
+
+The optional `lit_suffix` production is only used for certain numeric literals,
+but is reserved for future extension. That is, the above gives the lexical
+grammar, but a Rust parser will reject everything but the 12 special cases
+mentioned in [Number literals](reference/tokens.html#number-literals) in the
+reference.
+
+#### Character and string literals
+
+```antlr
+char_lit : '\x27' char_body '\x27' ;
+string_lit : '"' string_body * '"' | 'r' raw_string ;
+
+char_body : non_single_quote
+ | '\x5c' [ '\x27' | common_escape | unicode_escape ] ;
+
+string_body : non_double_quote
+ | '\x5c' [ '\x22' | common_escape | unicode_escape ] ;
+raw_string : '"' raw_string_body '"' | '#' raw_string '#' ;
+
+common_escape : '\x5c'
+ | 'n' | 'r' | 't' | '0'
+ | 'x' hex_digit 2
+unicode_escape : 'u' '{' hex_digit+ 6 '}';
+
+hex_digit : 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
+ | 'A' | 'B' | 'C' | 'D' | 'E' | 'F'
+ | dec_digit ;
+oct_digit : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' ;
+dec_digit : '0' | nonzero_dec ;
+nonzero_dec: '1' | '2' | '3' | '4'
+ | '5' | '6' | '7' | '8' | '9' ;
+```
+
+#### Byte and byte string literals
+
+```antlr
+byte_lit : "b\x27" byte_body '\x27' ;
+byte_string_lit : "b\x22" string_body * '\x22' | "br" raw_byte_string ;
+
+byte_body : ascii_non_single_quote
+ | '\x5c' [ '\x27' | common_escape ] ;
+
+byte_string_body : ascii_non_double_quote
+ | '\x5c' [ '\x22' | common_escape ] ;
+raw_byte_string : '"' raw_byte_string_body '"' | '#' raw_byte_string '#' ;
+
+```
+
+#### Number literals
+
+```antlr
+num_lit : nonzero_dec [ dec_digit | '_' ] * float_suffix ?
+ | '0' [ [ dec_digit | '_' ] * float_suffix ?
+ | 'b' [ '1' | '0' | '_' ] +
+ | 'o' [ oct_digit | '_' ] +
+ | 'x' [ hex_digit | '_' ] + ] ;
+
+float_suffix : [ exponent | '.' dec_lit exponent ? ] ? ;
+
+exponent : ['E' | 'e'] ['-' | '+' ] ? dec_lit ;
+dec_lit : [ dec_digit | '_' ] + ;
+```
+
+#### Boolean literals
+
+```antlr
+bool_lit : [ "true" | "false" ] ;
+```
+
+The two values of the boolean type are written `true` and `false`.
+
+### Symbols
+
+```antlr
+symbol : "::" | "->"
+ | '#' | '[' | ']' | '(' | ')' | '{' | '}'
+ | ',' | ';' ;
+```
+
+Symbols are a general class of printable [tokens](#tokens) that play structural
+roles in a variety of grammar productions. They are cataloged here for
+completeness as the set of remaining miscellaneous printable tokens that do not
+otherwise appear as [unary operators](#unary-operator-expressions), [binary
+operators](#binary-operator-expressions), or [keywords](#keywords).
+
+## Paths
+
+```antlr
+expr_path : [ "::" ] ident [ "::" expr_path_tail ] + ;
+expr_path_tail : '<' type_expr [ ',' type_expr ] + '>'
+ | expr_path ;
+
+type_path : ident [ type_path_tail ] + ;
+type_path_tail : '<' type_expr [ ',' type_expr ] + '>'
+ | "::" type_path ;
+```
+
+# Syntax extensions
+
+## Macros
+
+```antlr
+expr_macro_rules : "macro_rules" '!' ident '(' macro_rule * ')' ';'
+ | "macro_rules" '!' ident '{' macro_rule * '}' ;
+macro_rule : '(' matcher * ')' "=>" '(' transcriber * ')' ';' ;
+matcher : '(' matcher * ')' | '[' matcher * ']'
+ | '{' matcher * '}' | '$' ident ':' ident
+ | '$' '(' matcher * ')' sep_token? [ '*' | '+' ]
+ | non_special_token ;
+transcriber : '(' transcriber * ')' | '[' transcriber * ']'
+ | '{' transcriber * '}' | '$' ident
+ | '$' '(' transcriber * ')' sep_token? [ '*' | '+' ]
+ | non_special_token ;
+```
+
+# Crates and source files
+
+**FIXME:** grammar? What production covers #![crate_id = "foo"] ?
+
+# Items and attributes
+
+**FIXME:** grammar?
+
+## Items
+
+```antlr
+item : vis ? mod_item | fn_item | type_item | struct_item | enum_item
+ | const_item | static_item | trait_item | impl_item | extern_block_item ;
+```
+
+### Type Parameters
+
+**FIXME:** grammar?
+
+### Modules
+
+```antlr
+mod_item : "mod" ident ( ';' | '{' mod '}' );
+mod : [ view_item | item ] * ;
+```
+
+#### View items
+
+```antlr
+view_item : extern_crate_decl | use_decl ';' ;
+```
+
+##### Extern crate declarations
+
+```antlr
+extern_crate_decl : "extern" "crate" crate_name
+crate_name: ident | ( ident "as" ident )
+```
+
+##### Use declarations
+
+```antlr
+use_decl : vis ? "use" [ path "as" ident
+ | path_glob ] ;
+
+path_glob : ident [ "::" [ path_glob
+ | '*' ] ] ?
+ | '{' path_item [ ',' path_item ] * '}' ;
+
+path_item : ident | "self" ;
+```
+
+### Functions
+
+**FIXME:** grammar?
+
+#### Generic functions
+
+**FIXME:** grammar?
+
+#### Unsafety
+
+**FIXME:** grammar?
+
+##### Unsafe functions
+
+**FIXME:** grammar?
+
+##### Unsafe blocks
+
+**FIXME:** grammar?
+
+#### Diverging functions
+
+**FIXME:** grammar?
+
+### Type definitions
+
+**FIXME:** grammar?
+
+### Structures
+
+**FIXME:** grammar?
+
+### Enumerations
+
+**FIXME:** grammar?
+
+### Constant items
+
+```antlr
+const_item : "const" ident ':' type '=' expr ';' ;
+```
+
+### Static items
+
+```antlr
+static_item : "static" ident ':' type '=' expr ';' ;
+```
+
+#### Mutable statics
+
+**FIXME:** grammar?
+
+### Traits
+
+**FIXME:** grammar?
+
+### Implementations
+
+**FIXME:** grammar?
+
+### External blocks
+
+```antlr
+extern_block_item : "extern" '{' extern_block '}' ;
+extern_block : [ foreign_fn ] * ;
+```
+
+## Visibility and Privacy
+
+```antlr
+vis : "pub" ;
+```
+### Re-exporting and Visibility
+
+See [Use declarations](#use-declarations).
+
+## Attributes
+
+```antlr
+attribute : '#' '!' ? '[' meta_item ']' ;
+meta_item : ident [ '=' literal
+ | '(' meta_seq ')' ] ? ;
+meta_seq : meta_item [ ',' meta_seq ] ? ;
+```
+
+# Statements and expressions
+
+## Statements
+
+```antlr
+stmt : decl_stmt | expr_stmt | ';' ;
+```
+
+### Declaration statements
+
+```antlr
+decl_stmt : item | let_decl ;
+```
+
+#### Item declarations
+
+See [Items](#items).
+
+#### Variable declarations
+
+```antlr
+let_decl : "let" pat [':' type ] ? [ init ] ? ';' ;
+init : [ '=' ] expr ;
+```
+
+### Expression statements
+
+```antlr
+expr_stmt : expr ';' ;
+```
+
+## Expressions
+
+```antlr
+expr : literal | path | tuple_expr | unit_expr | struct_expr
+ | block_expr | method_call_expr | field_expr | array_expr
+ | idx_expr | range_expr | unop_expr | binop_expr
+ | paren_expr | call_expr | lambda_expr | while_expr
+ | loop_expr | break_expr | continue_expr | for_expr
+ | if_expr | match_expr | if_let_expr | while_let_expr
+ | return_expr ;
+```
+
+#### Lvalues, rvalues and temporaries
+
+**FIXME:** grammar?
+
+#### Moved and copied types
+
+**FIXME:** Do we want to capture this in the grammar as different productions?
+
+### Literal expressions
+
+See [Literals](#literals).
+
+### Path expressions
+
+See [Paths](#paths).
+
+### Tuple expressions
+
+```antlr
+tuple_expr : '(' [ expr [ ',' expr ] * | expr ',' ] ? ')' ;
+```
+
+### Unit expressions
+
+```antlr
+unit_expr : "()" ;
+```
+
+### Structure expressions
+
+```antlr
+struct_expr_field_init : ident | ident ':' expr ;
+struct_expr : expr_path '{' struct_expr_field_init
+ [ ',' struct_expr_field_init ] *
+ [ ".." expr ] '}' |
+ expr_path '(' expr
+ [ ',' expr ] * ')' |
+ expr_path ;
+```
+
+### Block expressions
+
+```antlr
+block_expr : '{' [ stmt | item ] *
+ [ expr ] '}' ;
+```
+
+### Method-call expressions
+
+```antlr
+method_call_expr : expr '.' ident paren_expr_list ;
+```
+
+### Field expressions
+
+```antlr
+field_expr : expr '.' ident ;
+```
+
+### Array expressions
+
+```antlr
+array_expr : '[' "mut" ? array_elems? ']' ;
+
+array_elems : [expr [',' expr]*] | [expr ';' expr] ;
+```
+
+### Index expressions
+
+```antlr
+idx_expr : expr '[' expr ']' ;
+```
+
+### Range expressions
+
+```antlr
+range_expr : expr ".." expr |
+ expr ".." |
+ ".." expr |
+ ".." ;
+```
+
+### Unary operator expressions
+
+```antlr
+unop_expr : unop expr ;
+unop : '-' | '*' | '!' ;
+```
+
+### Binary operator expressions
+
+```antlr
+binop_expr : expr binop expr | type_cast_expr
+ | assignment_expr | compound_assignment_expr ;
+binop : arith_op | bitwise_op | lazy_bool_op | comp_op
+```
+
+#### Arithmetic operators
+
+```antlr
+arith_op : '+' | '-' | '*' | '/' | '%' ;
+```
+
+#### Bitwise operators
+
+```antlr
+bitwise_op : '&' | '|' | '^' | "<<" | ">>" ;
+```
+
+#### Lazy boolean operators
+
+```antlr
+lazy_bool_op : "&&" | "||" ;
+```
+
+#### Comparison operators
+
+```antlr
+comp_op : "==" | "!=" | '<' | '>' | "<=" | ">=" ;
+```
+
+#### Type cast expressions
+
+```antlr
+type_cast_expr : value "as" type ;
+```
+
+#### Assignment expressions
+
+```antlr
+assignment_expr : expr '=' expr ;
+```
+
+#### Compound assignment expressions
+
+```antlr
+compound_assignment_expr : expr [ arith_op | bitwise_op ] '=' expr ;
+```
+
+### Grouped expressions
+
+```antlr
+paren_expr : '(' expr ')' ;
+```
+
+### Call expressions
+
+```antlr
+expr_list : [ expr [ ',' expr ]* ] ? ;
+paren_expr_list : '(' expr_list ')' ;
+call_expr : expr paren_expr_list ;
+```
+
+### Lambda expressions
+
+```antlr
+ident_list : [ ident [ ',' ident ]* ] ? ;
+lambda_expr : '|' ident_list '|' expr ;
+```
+
+### While loops
+
+```antlr
+while_expr : [ lifetime ':' ] ? "while" no_struct_literal_expr '{' block '}' ;
+```
+
+### Infinite loops
+
+```antlr
+loop_expr : [ lifetime ':' ] ? "loop" '{' block '}';
+```
+
+### Break expressions
+
+```antlr
+break_expr : "break" [ lifetime ] ?;
+```
+
+### Continue expressions
+
+```antlr
+continue_expr : "continue" [ lifetime ] ?;
+```
+
+### For expressions
+
+```antlr
+for_expr : [ lifetime ':' ] ? "for" pat "in" no_struct_literal_expr '{' block '}' ;
+```
+
+### If expressions
+
+```antlr
+if_expr : "if" no_struct_literal_expr '{' block '}'
+ else_tail ? ;
+
+else_tail : "else" [ if_expr | if_let_expr
+ | '{' block '}' ] ;
+```
+
+### Match expressions
+
+```antlr
+match_expr : "match" no_struct_literal_expr '{' match_arm * '}' ;
+
+match_arm : attribute * match_pat "=>" [ expr "," | '{' block '}' ] ;
+
+match_pat : pat [ '|' pat ] * [ "if" expr ] ? ;
+```
+
+### If let expressions
+
+```antlr
+if_let_expr : "if" "let" pat '=' expr '{' block '}'
+ else_tail ? ;
+```
+
+### While let loops
+
+```antlr
+while_let_expr : [ lifetime ':' ] ? "while" "let" pat '=' expr '{' block '}' ;
+```
+
+### Return expressions
+
+```antlr
+return_expr : "return" expr ? ;
+```
+
+# Type system
+
+**FIXME:** is this entire chapter relevant here? Or should it all have been covered by some production already?
+
+## Types
+
+### Primitive types
+
+**FIXME:** grammar?
+
+#### Machine types
+
+**FIXME:** grammar?
+
+#### Machine-dependent integer types
+
+**FIXME:** grammar?
+
+### Textual types
+
+**FIXME:** grammar?
+
+### Tuple types
+
+**FIXME:** grammar?
+
+### Array, and Slice types
+
+**FIXME:** grammar?
+
+### Structure types
+
+**FIXME:** grammar?
+
+### Enumerated types
+
+**FIXME:** grammar?
+
+### Pointer types
+
+**FIXME:** grammar?
+
+### Function types
+
+**FIXME:** grammar?
+
+### Closure types
+
+```antlr
+closure_type := [ 'unsafe' ] [ '<' lifetime-list '>' ] '|' arg-list '|'
+ [ ':' bound-list ] [ '->' type ]
+lifetime-list := lifetime | lifetime ',' lifetime-list
+arg-list := ident ':' type | ident ':' type ',' arg-list
+```
+
+### Never type
+An empty type
+
+```antlr
+never_type : "!" ;
+```
+
+### Object types
+
+**FIXME:** grammar?
+
+### Type parameters
+
+**FIXME:** grammar?
+
+### Type parameter bounds
+
+```antlr
+bound-list := bound | bound '+' bound-list '+' ?
+bound := ty_bound | lt_bound
+lt_bound := lifetime
+ty_bound := ty_bound_noparen | (ty_bound_noparen)
+ty_bound_noparen := [?] [ for ] simple_path
+```
+
+### Self types
+
+**FIXME:** grammar?
+
+## Type kinds
+
+**FIXME:** this is probably not relevant to the grammar...
+
+# Memory and concurrency models
+
+**FIXME:** is this entire chapter relevant here? Or should it all have been covered by some production already?
+
+## Memory model
+
+### Memory allocation and lifetime
+
+### Memory ownership
+
+### Variables
+
+### Boxes
+
+## Threads
+
+### Communication between threads
+
+### Thread lifecycle
diff --git a/src/doc/nomicon b/src/doc/nomicon
index 5004ad30d69f9..4374786f0b4bf 160000
--- a/src/doc/nomicon
+++ b/src/doc/nomicon
@@ -1 +1 @@
-Subproject commit 5004ad30d69f93553ceef74439fea2159d1f769e
+Subproject commit 4374786f0b4bf0606b35d5c30a9681f342e5707b
diff --git a/src/doc/reference b/src/doc/reference
index 5b9d2fcefadfc..fa5dfb832ef8a 160000
--- a/src/doc/reference
+++ b/src/doc/reference
@@ -1 +1 @@
-Subproject commit 5b9d2fcefadfc32fceafacfc0dd9441d9b57dd94
+Subproject commit fa5dfb832ef8a7568e17dabf612f486d641ff4ac
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
index 0b111eaae36cc..67cfbf31df880 160000
--- a/src/doc/rust-by-example
+++ b/src/doc/rust-by-example
@@ -1 +1 @@
-Subproject commit 0b111eaae36cc4b4997684be853882a59e2c7ca7
+Subproject commit 67cfbf31df880728dcf7cb35b15b028ec92caf31
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index b603c7b231e68..3cda8d927973c 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -10,11 +10,9 @@
- [Warn-by-default lints](lints/listing/warn-by-default.md)
- [Deny-by-default lints](lints/listing/deny-by-default.md)
- [Codegen options](codegen-options/index.md)
-- [JSON Output](json.md)
- [Targets](targets/index.md)
- [Built-in Targets](targets/built-in.md)
- [Custom Targets](targets/custom.md)
- - [Known Issues](targets/known-issues.md)
- [Profile-guided Optimization](profile-guided-optimization.md)
- [Linker-plugin based LTO](linker-plugin-lto.md)
- [Contributing to `rustc`](contributing.md)
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index f5d5f2089d7e7..5c41acc6581c5 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -61,8 +61,6 @@ enabling or disabling a feature.
To see the valid options and an example of use, run `rustc --print
target-features`.
-Using this flag is unsafe and might result in [undefined runtime behavior](../targets/known-issues.md).
-
## passes
This flag can be used to add extra LLVM passes to the compilation.
@@ -107,7 +105,7 @@ flag will turn that behavior off.
## no-vectorize-slp
-By default, `rustc` will attempt to vectorize code using [superword-level
+By default, `rustc` will attempt to vectorize loops using [superword-level
parallelism](https://llvm.org/docs/Vectorizers.html#the-slp-vectorizer). This
flag will turn that behavior off.
diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md
index bdb3c5196585e..5eea9c8687900 100644
--- a/src/doc/rustc/src/command-line-arguments.md
+++ b/src/doc/rustc/src/command-line-arguments.md
@@ -92,7 +92,6 @@ information about editions may be found in the [edition guide].
[edition guide]: ../edition-guide/introduction.html
## `--emit`: specifies the types of output files to generate
-
This flag controls the types of output files generated by the compiler. It
accepts a comma-separated list of values, and may be specified multiple times.
@@ -145,7 +144,7 @@ of print values are:
target CPU may be selected with the `-C target-cpu=val` flag.
- `target-features` — List of available target features for the current
target. Target features may be enabled with the `-C target-feature=val`
- flag. This flag is unsafe. See [known issues](targets/known-issues.md) for more details.
+ flag.
- `relocation-models` — List of relocation models. Relocation models may be
selected with the `-C relocation-model=val` flag.
- `code-models` — List of code models. Code models may be selected with the
@@ -242,13 +241,12 @@ The "sysroot" is where `rustc` looks for the crates that come with the Rust
distribution; this flag allows that to be overridden.
## `--error-format`: control how errors are produced
-
This flag lets you control the format of messages. Messages are printed to
stderr. The valid options are:
- `human` — Human-readable output. This is the default.
-- `json` — Structured JSON output. See [the JSON chapter] for more detail.
+- `json` — Structured JSON output.
- `short` — Short, one-line messages.
## `--color`: configure coloring of output
@@ -275,7 +273,6 @@ pathname syntax. For example `--remap-path-prefix foo=bar` will match
`foo/lib.rs` but not `./foo/lib.rs`.
## `--json`: configure json messages printed by the compiler
-
When the `--error-format=json` option is passed to rustc then all of the
compiler's diagnostic output will be emitted in the form of JSON blobs. The
@@ -308,13 +305,9 @@ to customize the output:
Note that it is invalid to combine the `--json` argument with the `--color`
argument, and it is required to combine `--json` with `--error-format=json`.
-See [the JSON chapter] for more detail.
-
## `@path`: load command-line flags from a path
If you specify `@path` on the command-line, then it will open `path` and read
command line options from it. These options are one per line; a blank line indicates
an empty option. The file can use Unix or Windows style line endings, and must be
encoded as UTF-8.
-
-[the JSON chapter]: json.md
diff --git a/src/doc/rustc/src/json.md b/src/doc/rustc/src/json.md
deleted file mode 100644
index b737849516310..0000000000000
--- a/src/doc/rustc/src/json.md
+++ /dev/null
@@ -1,231 +0,0 @@
-# JSON Output
-
-This chapter documents the JSON structures emitted by `rustc`. JSON may be
-enabled with the [`--error-format=json` flag][option-error-format]. Additional
-options may be specified with the [`--json` flag][option-json] which can
-change which messages are generated, and the format of the messages.
-
-JSON messages are emitted one per line to stderr.
-
-If parsing the output with Rust, the
-[`cargo_metadata`](https://crates.io/crates/cargo_metadata) crate provides
-some support for parsing the messages.
-
-When parsing, care should be taken to be forwards-compatible with future changes
-to the format. Optional values may be `null`. New fields may be added. Enumerated
-fields like "level" or "suggestion_applicability" may add new values.
-
-## Diagnostics
-
-Diagnostic messages provide errors or possible concerns generated during
-compilation. `rustc` provides detailed information about where the diagnostic
-originates, along with hints and suggestions.
-
-Diagnostics are arranged in a parent/child relationship where the parent
-diagnostic value is the core of the diagnostic, and the attached children
-provide additional context, help, and information.
-
-Diagnostics have the following format:
-
-```javascript
-{
- /* The primary message. */
- "message": "unused variable: `x`",
- /* The diagnostic code.
- Some messages may set this value to null.
- */
- "code": {
- /* A unique string identifying which diagnostic triggered. */
- "code": "unused_variables",
- /* An optional string explaining more detail about the diagnostic code. */
- "explanation": null
- },
- /* The severity of the diagnostic.
- Values may be:
- - "error": A fatal error that prevents compilation.
- - "warning": A possible error or concern.
- - "note": Additional information or context about the diagnostic.
- - "help": A suggestion on how to resolve the diagnostic.
- - "failure-note": A note attached to the message for further information.
- - "error: internal compiler error": Indicates a bug within the compiler.
- */
- "level": "warning",
- /* An array of source code locations to point out specific details about
- where the diagnostic originates from. This may be empty, for example
- for some global messages, or child messages attached to a parent.
-
- Character offsets are offsets of Unicode Scalar Values.
- */
- "spans": [
- {
- /* The file where the span is located.
- For spans located within a macro expansion, this will be the
- name of the expanded macro in the format "".
- */
- "file_name": "lib.rs",
- /* The byte offset where the span starts (0-based, inclusive). */
- "byte_start": 21,
- /* The byte offset where the span ends (0-based, exclusive). */
- "byte_end": 22,
- /* The first line number of the span (1-based, inclusive). */
- "line_start": 2,
- /* The last line number of the span (1-based, inclusive). */
- "line_end": 2,
- /* The first character offset of the line_start (1-based, inclusive). */
- "column_start": 9,
- /* The last character offset of the line_end (1-based, exclusive). */
- "column_end": 10,
- /* Whether or not this is the "primary" span.
-
- This indicates that this span is the focal point of the
- diagnostic.
-
- There are rare cases where multiple spans may be marked as
- primary. For example, "immutable borrow occurs here" and
- "mutable borrow ends here" can be two separate primary spans.
-
- The top (parent) message should always have at least one
- primary span, unless it has zero spans. Child messages may have
- zero or more primary spans.
- */
- "is_primary": true,
- /* An array of objects showing the original source code for this
- span. This shows the entire lines of text where the span is
- located. A span across multiple lines will have a separate
- value for each line.
- */
- "text": [
- {
- /* The entire line of the original source code. */
- "text": " let x = 123;",
- /* The first character offset of the line of
- where the span covers this line (1-based, inclusive). */
- "highlight_start": 9,
- /* The last character offset of the line of
- where the span covers this line (1-based, exclusive). */
- "highlight_end": 10
- }
- ],
- /* An optional message to display at this span location.
- This is typically null for primary spans.
- */
- "label": null,
- /* An optional string of a suggested replacement for this span to
- solve the issue. Tools may try to replace the contents of the
- span with this text.
- */
- "suggested_replacement": null,
- /* An optional string that indicates the confidence of the
- "suggested_replacement". Tools may use this value to determine
- whether or not suggestions should be automatically applied.
-
- Possible values may be:
- - "MachineApplicable": The suggestion is definitely what the
- user intended. This suggestion should be automatically
- applied.
- - "MaybeIncorrect": The suggestion may be what the user
- intended, but it is uncertain. The suggestion should result
- in valid Rust code if it is applied.
- - "HasPlaceholders": The suggestion contains placeholders like
- `(...)`. The suggestion cannot be applied automatically
- because it will not result in valid Rust code. The user will
- need to fill in the placeholders.
- - "Unspecified": The applicability of the suggestion is unknown.
- */
- "suggestion_applicability": null,
- /* An optional object indicating the expansion of a macro within
- this span.
-
- If a message occurs within a macro invocation, this object will
- provide details of where within the macro expansion the message
- is located.
- */
- "expansion": {
- /* The span of the macro invocation.
- Uses the same span definition as the "spans" array.
- */
- "span": {/*...*/}
- /* Name of the macro, such as "foo!" or "#[derive(Eq)]". */
- "macro_decl_name": "some_macro!",
- /* Optional span where the relevant part of the macro is
- defined. */
- "def_site_span": {/*...*/},
- }
- }
- ],
- /* Array of attached diagnostic messages.
- This is an array of objects using the same format as the parent
- message. Children are not nested (children do not themselves
- contain "children" definitions).
- */
- "children": [
- {
- "message": "`#[warn(unused_variables)]` on by default",
- "code": null,
- "level": "note",
- "spans": [],
- "children": [],
- "rendered": null
- },
- {
- "message": "consider prefixing with an underscore",
- "code": null,
- "level": "help",
- "spans": [
- {
- "file_name": "lib.rs",
- "byte_start": 21,
- "byte_end": 22,
- "line_start": 2,
- "line_end": 2,
- "column_start": 9,
- "column_end": 10,
- "is_primary": true,
- "text": [
- {
- "text": " let x = 123;",
- "highlight_start": 9,
- "highlight_end": 10
- }
- ],
- "label": null,
- "suggested_replacement": "_x",
- "suggestion_applicability": "MachineApplicable",
- "expansion": null
- }
- ],
- "children": [],
- "rendered": null
- }
- ],
- /* Optional string of the rendered version of the diagnostic as displayed
- by rustc. Note that this may be influenced by the `--json` flag.
- */
- "rendered": "warning: unused variable: `x`\n --> lib.rs:2:9\n |\n2 | let x = 123;\n | ^ help: consider prefixing with an underscore: `_x`\n |\n = note: `#[warn(unused_variables)]` on by default\n\n"
-}
-```
-
-## Artifact notifications
-
-Artifact notifications are emitted when the [`--json=artifacts`
-flag][option-json] is used. They indicate that a file artifact has been saved
-to disk. More information about emit kinds may be found in the [`--emit`
-flag][option-emit] documentation.
-
-```javascript
-{
- /* The filename that was generated. */
- "artifact": "libfoo.rlib",
- /* The kind of artifact that was generated. Possible values:
- - "link": The generated crate as specified by the crate-type.
- - "dep-info": The `.d` file with dependency information in a Makefile-like syntax.
- - "metadata": The Rust `.rmeta` file containing metadata about the crate.
- - "save-analysis": A JSON file emitted by the `-Zsave-analysis` feature.
- */
- "emit": "link"
-}
-```
-
-[option-emit]: command-line-arguments.md#option-emit
-[option-error-format]: command-line-arguments.md#option-error-format
-[option-json]: command-line-arguments.md#option-json
diff --git a/src/doc/rustc/src/lints/listing/deny-by-default.md b/src/doc/rustc/src/lints/listing/deny-by-default.md
index 5688e90ada129..6574267f18511 100644
--- a/src/doc/rustc/src/lints/listing/deny-by-default.md
+++ b/src/doc/rustc/src/lints/listing/deny-by-default.md
@@ -222,28 +222,3 @@ error: invalid `crate_type` value
| ^^^^^^^^^^^^^^^^^^^^
|
```
-
-## const-err
-
-This lint detects expressions that will always panic at runtime and would be an
-error in a `const` context.
-
-```rust,ignore
-let _ = [0; 4][4];
-```
-
-This will produce:
-
-```text
-error: index out of bounds: the len is 4 but the index is 4
- --> src/lib.rs:1:9
- |
-1 | let _ = [0; 4][4];
- | ^^^^^^^^^
- |
-```
-
-## order-dependent-trait-objects
-
-This lint detects a trait coherency violation that would allow creating two
-trait impls for the same dynamic trait object involving marker traits.
diff --git a/src/doc/rustc/src/lints/listing/warn-by-default.md b/src/doc/rustc/src/lints/listing/warn-by-default.md
index 813d7c4bafef8..e486240fda896 100644
--- a/src/doc/rustc/src/lints/listing/warn-by-default.md
+++ b/src/doc/rustc/src/lints/listing/warn-by-default.md
@@ -596,6 +596,30 @@ warning: function cannot return without recursing
|
```
+## unions-with-drop-fields
+
+This lint detects use of unions that contain fields with possibly non-trivial drop code. Some
+example code that triggers this lint:
+
+```rust
+#![feature(untagged_unions)]
+
+union U {
+ s: String,
+}
+```
+
+This will produce:
+
+```text
+warning: union contains a field with possibly non-trivial drop code, drop code of union fields is ignored when dropping the union
+ --> src/main.rs:4:5
+ |
+4 | s: String,
+ | ^^^^^^^^^
+ |
+```
+
## unknown-lints
This lint detects unrecognized lint attribute. Some
diff --git a/src/doc/rustc/src/profile-guided-optimization.md b/src/doc/rustc/src/profile-guided-optimization.md
index d066f4a9cf59c..38be07a6440da 100644
--- a/src/doc/rustc/src/profile-guided-optimization.md
+++ b/src/doc/rustc/src/profile-guided-optimization.md
@@ -125,17 +125,6 @@ RUSTFLAGS="-Cprofile-use=/tmp/pgo-data/merged.profdata" \
cargo build --release --target=x86_64-unknown-linux-gnu
```
-### Troubleshooting
-
-- It is recommended to pass `-Cllvm-args=-pgo-warn-missing-function` during the
- `-Cprofile-use` phase. LLVM by default does not warn if it cannot find
- profiling data for a given function. Enabling this warning will make it
- easier to spot errors in your setup.
-
-- There is a [known issue](https://github.com/rust-lang/cargo/issues/7416) in
- Cargo prior to version 1.39 that will prevent PGO from working correctly. Be
- sure to use Cargo 1.39 or newer when doing PGO.
-
## Further Reading
`rustc`'s PGO support relies entirely on LLVM's implementation of the feature
diff --git a/src/doc/rustc/src/targets/index.md b/src/doc/rustc/src/targets/index.md
index 5859df83f645b..3d63d072befe0 100644
--- a/src/doc/rustc/src/targets/index.md
+++ b/src/doc/rustc/src/targets/index.md
@@ -11,9 +11,3 @@ To compile to a particular target, use the `--target` flag:
```bash
$ rustc src/main.rs --target=wasm32-unknown-unknown
```
-## Target Features
-`x86`, and `ARMv8` are two popular CPU architectures. Their instruction sets form a common baseline across most CPUs. However, some CPUs extend these with custom instruction sets, e.g. vector (`AVX`), bitwise manipulation (`BMI`) or cryptographic (`AES`).
-
-Developers, who know on which CPUs their compiled code is going to run can choose to add (or remove) CPU specific instruction sets via the `-C target-feature=val` flag.
-
-Please note, that this flag is generally considered as unsafe. More details can be found in [this section](known-issues.md).
diff --git a/src/doc/rustc/src/targets/known-issues.md b/src/doc/rustc/src/targets/known-issues.md
deleted file mode 100644
index 89fd8ea6d32e9..0000000000000
--- a/src/doc/rustc/src/targets/known-issues.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Known Issues
-This section informs you about known "gotchas". Keep in mind, that this section is (and always will be) incomplete. For suggestions and amendments, feel free to [contribute](../contributing.md) to this guide.
-
-## Target Features
-Most target-feature problems arise, when mixing code that have the target-feature _enabled_ with code that have it _disabled_. If you want to avoid undefined behavior, it is recommended to build _all code_ (including the standard library and imported crates) with a common set of target-features.
-
-By default, compiling your code with the `-C target-feature` flag will not recompile the entire standard library and/or imported crates with matching target features. Therefore, target features are generally considered as unsafe. Using `#[target_feature]` on individual functions makes the function unsafe.
-
-Examples:
-
-| Target-Feature | Issue | Seen on | Description | Details |
-| -------------- | ----- | ------- | ----------- | ------- |
-| `+soft-float`
and
`-sse` | Segfaults and ABI mismatches | `x86` and `x86-64` | The `x86` and `x86_64` architecture uses SSE registers (aka `xmm`) for floating point operations. Using software emulated floats ("soft-floats") disables usage of `xmm` registers, but parts of Rust's core libraries (e.g. `std::f32` or `std::f64`) are compiled without soft-floats and expect parameters to be passed in `xmm` registers. This leads to ABI mismatches.
Attempting to compile with disabled SSE causes the same error, too. | [#63466](https://github.com/rust-lang/rust/issues/63466) |
diff --git a/src/doc/unstable-book/src/compiler-flags/report-time.md b/src/doc/unstable-book/src/compiler-flags/report-time.md
deleted file mode 100644
index ed4e9c6b56842..0000000000000
--- a/src/doc/unstable-book/src/compiler-flags/report-time.md
+++ /dev/null
@@ -1,80 +0,0 @@
-# `report-time`
-
-The tracking issue for this feature is: [#64888]
-
-[#64888]: https://github.com/rust-lang/rust/issues/64888
-
-------------------------
-
-The `report-time` feature adds a possibility to report execution time of the
-tests generated via `libtest`.
-
-This is unstable feature, so you have to provide `-Zunstable-options` to get
-this feature working.
-
-Sample usage command:
-
-```sh
-./test_executable -Zunstable-options --report-time
-```
-
-Available options:
-
-```sh
---report-time [plain|colored]
- Show execution time of each test. Awailable values:
- plain = do not colorize the execution time (default);
- colored = colorize output according to the `color`
- parameter value;
- Threshold values for colorized output can be
- configured via
- `RUST_TEST_TIME_UNIT`, `RUST_TEST_TIME_INTEGRATION`
- and
- `RUST_TEST_TIME_DOCTEST` environment variables.
- Expected format of environment variable is
- `VARIABLE=WARN_TIME,CRITICAL_TIME`.
- Not available for --format=terse
---ensure-time
- Treat excess of the test execution time limit as
- error.
- Threshold values for this option can be configured via
- `RUST_TEST_TIME_UNIT`, `RUST_TEST_TIME_INTEGRATION`
- and
- `RUST_TEST_TIME_DOCTEST` environment variables.
- Expected format of environment variable is
- `VARIABLE=WARN_TIME,CRITICAL_TIME`.
- `CRITICAL_TIME` here means the limit that should not be
- exceeded by test.
-```
-
-Example of the environment variable format:
-
-```sh
-RUST_TEST_TIME_UNIT=100,200
-```
-
-where 100 stands for warn time, and 200 stands for critical time.
-
-## Examples
-
-```sh
-cargo test --tests -- -Zunstable-options --report-time
- Finished dev [unoptimized + debuginfo] target(s) in 0.02s
- Running target/debug/deps/example-27fb188025bec02c
-
-running 3 tests
-test tests::unit_test_quick ... ok <0.000s>
-test tests::unit_test_warn ... ok <0.055s>
-test tests::unit_test_critical ... ok <0.110s>
-
-test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
-
- Running target/debug/deps/tests-cedb06f6526d15d9
-
-running 3 tests
-test unit_test_quick ... ok <0.000s>
-test unit_test_warn ... ok <0.550s>
-test unit_test_critical ... ok <1.100s>
-
-test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
-```
diff --git a/src/doc/unstable-book/src/language-features/non-exhaustive.md b/src/doc/unstable-book/src/language-features/non-exhaustive.md
new file mode 100644
index 0000000000000..907147c17ef8e
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/non-exhaustive.md
@@ -0,0 +1,76 @@
+# `non_exhaustive`
+
+The tracking issue for this feature is: [#44109]
+
+[#44109]: https://github.com/rust-lang/rust/issues/44109
+
+------------------------
+
+The `non_exhaustive` gate allows you to use the `#[non_exhaustive]` attribute
+on structs, enums and enum variants. When applied within a crate, users of the
+crate will need to use the `_` pattern when matching enums and use the `..`
+pattern when matching structs. Enum variants cannot be matched against.
+Structs and enum variants marked as `non_exhaustive` will not be able to
+be created normally outside of the defining crate. This is demonstrated
+below:
+
+```rust,ignore (pseudo-Rust)
+use std::error::Error as StdError;
+
+#[non_exhaustive]
+pub enum Error {
+ Message(String),
+ Other,
+}
+impl StdError for Error {
+ fn description(&self) -> &str {
+ // This will not error, despite being marked as non_exhaustive, as this
+ // enum is defined within the current crate, it can be matched
+ // exhaustively.
+ match *self {
+ Message(ref s) => s,
+ Other => "other or unknown error",
+ }
+ }
+}
+```
+
+```rust,ignore (pseudo-Rust)
+use mycrate::Error;
+
+// This will not error as the non_exhaustive Error enum has been matched with
+// a wildcard.
+match error {
+ Message(ref s) => ...,
+ Other => ...,
+ _ => ...,
+}
+```
+
+```rust,ignore (pseudo-Rust)
+#[non_exhaustive]
+pub struct Config {
+ pub window_width: u16,
+ pub window_height: u16,
+}
+
+// We can create structs as normal within the defining crate when marked as
+// non_exhaustive.
+let config = Config { window_width: 640, window_height: 480 };
+
+// We can match structs exhaustively when within the defining crate.
+if let Ok(Config { window_width, window_height }) = load_config() {
+ // ...
+}
+```
+
+```rust,ignore (pseudo-Rust)
+use mycrate::Config;
+
+// We cannot create a struct like normal if it has been marked as
+// non_exhaustive.
+let config = Config { window_width: 640, window_height: 480 };
+// By adding the `..` we can match the config as below outside of the crate
+// when marked non_exhaustive.
+let &Config { window_width, window_height, .. } = config;
+```
diff --git a/src/doc/unstable-book/src/language-features/track-caller.md b/src/doc/unstable-book/src/language-features/track-caller.md
deleted file mode 100644
index afc11a2b9492c..0000000000000
--- a/src/doc/unstable-book/src/language-features/track-caller.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# `track_caller`
-
-The tracking issue for this feature is: [#47809](https://github.com/rust-lang/rust/issues/47809).
-
-------------------------
diff --git a/src/grammar/.gitignore b/src/grammar/.gitignore
new file mode 100644
index 0000000000000..3e4498759434f
--- /dev/null
+++ b/src/grammar/.gitignore
@@ -0,0 +1,3 @@
+*.class
+*.java
+*.tokens
diff --git a/src/grammar/lexer.l b/src/grammar/lexer.l
new file mode 100644
index 0000000000000..1feb781b2b39f
--- /dev/null
+++ b/src/grammar/lexer.l
@@ -0,0 +1,350 @@
+%{
+#include
+#include
+
+static int num_hashes;
+static int end_hashes;
+static int saw_non_hash;
+
+%}
+
+%option stack
+%option yylineno
+
+%x str
+%x rawstr
+%x rawstr_esc_begin
+%x rawstr_esc_body
+%x rawstr_esc_end
+%x byte
+%x bytestr
+%x rawbytestr
+%x rawbytestr_nohash
+%x pound
+%x shebang_or_attr
+%x ltorchar
+%x linecomment
+%x doc_line
+%x blockcomment
+%x doc_block
+%x suffix
+
+ident [a-zA-Z\x80-\xff_][a-zA-Z0-9\x80-\xff_]*
+
+%%
+
+{ident} { BEGIN(INITIAL); }
+(.|\n) { yyless(0); BEGIN(INITIAL); }
+
+[ \n\t\r] { }
+
+\xef\xbb\xbf {
+ // UTF-8 byte order mark (BOM), ignore if in line 1, error otherwise
+ if (yyget_lineno() != 1) {
+ return -1;
+ }
+}
+
+\/\/(\/|\!) { BEGIN(doc_line); yymore(); }
+\n { BEGIN(INITIAL);
+ yyleng--;
+ yytext[yyleng] = 0;
+ return ((yytext[2] == '!') ? INNER_DOC_COMMENT : OUTER_DOC_COMMENT);
+ }
+[^\n]* { yymore(); }
+
+\/\/|\/\/\/\/ { BEGIN(linecomment); }
+\n { BEGIN(INITIAL); }
+[^\n]* { }
+
+\/\*(\*|\!)[^*] { yy_push_state(INITIAL); yy_push_state(doc_block); yymore(); }
+\/\* { yy_push_state(doc_block); yymore(); }
+\*\/ {
+ yy_pop_state();
+ if (yy_top_state() == doc_block) {
+ yymore();
+ } else {
+ return ((yytext[2] == '!') ? INNER_DOC_COMMENT : OUTER_DOC_COMMENT);
+ }
+}
+(.|\n) { yymore(); }
+
+\/\* { yy_push_state(blockcomment); }
+\/\* { yy_push_state(blockcomment); }
+\*\/ { yy_pop_state(); }
+(.|\n) { }
+
+_ { return UNDERSCORE; }
+abstract { return ABSTRACT; }
+alignof { return ALIGNOF; }
+as { return AS; }
+become { return BECOME; }
+box { return BOX; }
+break { return BREAK; }
+catch { return CATCH; }
+const { return CONST; }
+continue { return CONTINUE; }
+crate { return CRATE; }
+default { return DEFAULT; }
+do { return DO; }
+else { return ELSE; }
+enum { return ENUM; }
+extern { return EXTERN; }
+false { return FALSE; }
+final { return FINAL; }
+fn { return FN; }
+for { return FOR; }
+if { return IF; }
+impl { return IMPL; }
+in { return IN; }
+let { return LET; }
+loop { return LOOP; }
+macro { return MACRO; }
+match { return MATCH; }
+mod { return MOD; }
+move { return MOVE; }
+mut { return MUT; }
+offsetof { return OFFSETOF; }
+override { return OVERRIDE; }
+priv { return PRIV; }
+proc { return PROC; }
+pure { return PURE; }
+pub { return PUB; }
+ref { return REF; }
+return { return RETURN; }
+self { return SELF; }
+sizeof { return SIZEOF; }
+static { return STATIC; }
+struct { return STRUCT; }
+super { return SUPER; }
+trait { return TRAIT; }
+true { return TRUE; }
+type { return TYPE; }
+typeof { return TYPEOF; }
+union { return UNION; }
+unsafe { return UNSAFE; }
+unsized { return UNSIZED; }
+use { return USE; }
+virtual { return VIRTUAL; }
+where { return WHERE; }
+while { return WHILE; }
+yield { return YIELD; }
+
+{ident} { return IDENT; }
+
+0x[0-9a-fA-F_]+ { BEGIN(suffix); return LIT_INTEGER; }
+0o[0-7_]+ { BEGIN(suffix); return LIT_INTEGER; }
+0b[01_]+ { BEGIN(suffix); return LIT_INTEGER; }
+[0-9][0-9_]* { BEGIN(suffix); return LIT_INTEGER; }
+[0-9][0-9_]*\.(\.|[a-zA-Z]) { yyless(yyleng - 2); BEGIN(suffix); return LIT_INTEGER; }
+
+[0-9][0-9_]*\.[0-9_]*([eE][-\+]?[0-9_]+)? { BEGIN(suffix); return LIT_FLOAT; }
+[0-9][0-9_]*(\.[0-9_]*)?[eE][-\+]?[0-9_]+ { BEGIN(suffix); return LIT_FLOAT; }
+
+; { return ';'; }
+, { return ','; }
+\.\.\. { return DOTDOTDOT; }
+\.\. { return DOTDOT; }
+\. { return '.'; }
+\( { return '('; }
+\) { return ')'; }
+\{ { return '{'; }
+\} { return '}'; }
+\[ { return '['; }
+\] { return ']'; }
+@ { return '@'; }
+# { BEGIN(pound); yymore(); }
+\! { BEGIN(shebang_or_attr); yymore(); }
+\[ {
+ BEGIN(INITIAL);
+ yyless(2);
+ return SHEBANG;
+}
+[^\[\n]*\n {
+ // Since the \n was eaten as part of the token, yylineno will have
+ // been incremented to the value 2 if the shebang was on the first
+ // line. This yyless undoes that, setting yylineno back to 1.
+ yyless(yyleng - 1);
+ if (yyget_lineno() == 1) {
+ BEGIN(INITIAL);
+ return SHEBANG_LINE;
+ } else {
+ BEGIN(INITIAL);
+ yyless(2);
+ return SHEBANG;
+ }
+}
+. { BEGIN(INITIAL); yyless(1); return '#'; }
+
+\~ { return '~'; }
+:: { return MOD_SEP; }
+: { return ':'; }
+\$ { return '$'; }
+\? { return '?'; }
+
+== { return EQEQ; }
+=> { return FAT_ARROW; }
+= { return '='; }
+\!= { return NE; }
+\! { return '!'; }
+\<= { return LE; }
+\<\< { return SHL; }
+\<\<= { return SHLEQ; }
+\< { return '<'; }
+\>= { return GE; }
+\>\> { return SHR; }
+\>\>= { return SHREQ; }
+\> { return '>'; }
+
+\x27 { BEGIN(ltorchar); yymore(); }
+static { BEGIN(INITIAL); return STATIC_LIFETIME; }
+{ident} { BEGIN(INITIAL); return LIFETIME; }
+\\[nrt\\\x27\x220]\x27 { BEGIN(suffix); return LIT_CHAR; }
+\\x[0-9a-fA-F]{2}\x27 { BEGIN(suffix); return LIT_CHAR; }
+\\u\{([0-9a-fA-F]_*){1,6}\}\x27 { BEGIN(suffix); return LIT_CHAR; }
+.\x27 { BEGIN(suffix); return LIT_CHAR; }
+[\x80-\xff]{2,4}\x27 { BEGIN(suffix); return LIT_CHAR; }
+<> { BEGIN(INITIAL); return -1; }
+
+b\x22 { BEGIN(bytestr); yymore(); }
+\x22 { BEGIN(suffix); return LIT_BYTE_STR; }
+
+<> { return -1; }
+\\[n\nrt\\\x27\x220] { yymore(); }
+\\x[0-9a-fA-F]{2} { yymore(); }
+\\u\{([0-9a-fA-F]_*){1,6}\} { yymore(); }
+\\[^n\nrt\\\x27\x220] { return -1; }
+(.|\n) { yymore(); }
+
+br\x22 { BEGIN(rawbytestr_nohash); yymore(); }
+\x22 { BEGIN(suffix); return LIT_BYTE_STR_RAW; }
+(.|\n) { yymore(); }
+<> { return -1; }
+
+br/# {
+ BEGIN(rawbytestr);
+ yymore();
+ num_hashes = 0;
+ saw_non_hash = 0;
+ end_hashes = 0;
+}
+# {
+ if (!saw_non_hash) {
+ num_hashes++;
+ } else if (end_hashes != 0) {
+ end_hashes++;
+ if (end_hashes == num_hashes) {
+ BEGIN(INITIAL);
+ return LIT_BYTE_STR_RAW;
+ }
+ }
+ yymore();
+}
+\x22# {
+ end_hashes = 1;
+ if (end_hashes == num_hashes) {
+ BEGIN(INITIAL);
+ return LIT_BYTE_STR_RAW;
+ }
+ yymore();
+}
+(.|\n) {
+ if (!saw_non_hash) {
+ saw_non_hash = 1;
+ }
+ if (end_hashes != 0) {
+ end_hashes = 0;
+ }
+ yymore();
+}
+<> { return -1; }
+
+b\x27 { BEGIN(byte); yymore(); }
+\\[nrt\\\x27\x220]\x27 { BEGIN(INITIAL); return LIT_BYTE; }
+\\x[0-9a-fA-F]{2}\x27 { BEGIN(INITIAL); return LIT_BYTE; }
+\\u([0-9a-fA-F]_*){4}\x27 { BEGIN(INITIAL); return LIT_BYTE; }
+\\U([0-9a-fA-F]_*){8}\x27 { BEGIN(INITIAL); return LIT_BYTE; }
+.\x27 { BEGIN(INITIAL); return LIT_BYTE; }
+<> { BEGIN(INITIAL); return -1; }
+
+r\x22 { BEGIN(rawstr); yymore(); }
+\x22 { BEGIN(suffix); return LIT_STR_RAW; }
+(.|\n) { yymore(); }
+<> { return -1; }
+
+r/# {
+ BEGIN(rawstr_esc_begin);
+ yymore();
+ num_hashes = 0;
+ saw_non_hash = 0;
+ end_hashes = 0;
+}
+
+# {
+ num_hashes++;
+ yymore();
+}
+\x22 {
+ BEGIN(rawstr_esc_body);
+ yymore();
+}
+(.|\n) { return -1; }
+
+\x22/# {
+ BEGIN(rawstr_esc_end);
+ yymore();
+ }
+(.|\n) {
+ yymore();
+ }
+
+# {
+ end_hashes++;
+ if (end_hashes == num_hashes) {
+ BEGIN(INITIAL);
+ return LIT_STR_RAW;
+ }
+ yymore();
+ }
+[^#] {
+ end_hashes = 0;
+ BEGIN(rawstr_esc_body);
+ yymore();
+ }
+
+<> { return -1; }
+
+\x22 { BEGIN(str); yymore(); }
+\x22 { BEGIN(suffix); return LIT_STR; }
+
+<> { return -1; }
+\\[n\nr\rt\\\x27\x220] { yymore(); }
+\\x[0-9a-fA-F]{2} { yymore(); }
+\\u\{([0-9a-fA-F]_*){1,6}\} { yymore(); }
+\\[^n\nrt\\\x27\x220] { return -1; }
+(.|\n) { yymore(); }
+
+\<- { return LARROW; }
+-\> { return RARROW; }
+- { return '-'; }
+-= { return MINUSEQ; }
+&& { return ANDAND; }
+& { return '&'; }
+&= { return ANDEQ; }
+\|\| { return OROR; }
+\| { return '|'; }
+\|= { return OREQ; }
+\+ { return '+'; }
+\+= { return PLUSEQ; }
+\* { return '*'; }
+\*= { return STAREQ; }
+\/ { return '/'; }
+\/= { return SLASHEQ; }
+\^ { return '^'; }
+\^= { return CARETEQ; }
+% { return '%'; }
+%= { return PERCENTEQ; }
+
+<> { return 0; }
+
+%%
diff --git a/src/grammar/parser-lalr-main.c b/src/grammar/parser-lalr-main.c
new file mode 100644
index 0000000000000..6348190cc140b
--- /dev/null
+++ b/src/grammar/parser-lalr-main.c
@@ -0,0 +1,193 @@
+#include
+#include
+#include
+#include
+
+extern int yylex();
+extern int rsparse();
+
+#define PUSHBACK_LEN 4
+
+static char pushback[PUSHBACK_LEN];
+static int verbose;
+
+void print(const char* format, ...) {
+ va_list args;
+ va_start(args, format);
+ if (verbose) {
+ vprintf(format, args);
+ }
+ va_end(args);
+}
+
+// If there is a non-null char at the head of the pushback queue,
+// dequeue it and shift the rest of the queue forwards. Otherwise,
+// return the token from calling yylex.
+int rslex() {
+ if (pushback[0] == '\0') {
+ return yylex();
+ } else {
+ char c = pushback[0];
+ memmove(pushback, pushback + 1, PUSHBACK_LEN - 1);
+ pushback[PUSHBACK_LEN - 1] = '\0';
+ return c;
+ }
+}
+
+// Note: this does nothing if the pushback queue is full. As long as
+// there aren't more than PUSHBACK_LEN consecutive calls to push_back
+// in an action, this shouldn't be a problem.
+void push_back(char c) {
+ for (int i = 0; i < PUSHBACK_LEN; ++i) {
+ if (pushback[i] == '\0') {
+ pushback[i] = c;
+ break;
+ }
+ }
+}
+
+extern int rsdebug;
+
+struct node {
+ struct node *next;
+ struct node *prev;
+ int own_string;
+ char const *name;
+ int n_elems;
+ struct node *elems[];
+};
+
+struct node *nodes = NULL;
+int n_nodes;
+
+struct node *mk_node(char const *name, int n, ...) {
+ va_list ap;
+ int i = 0;
+ unsigned sz = sizeof(struct node) + (n * sizeof(struct node *));
+ struct node *nn, *nd = (struct node *)malloc(sz);
+
+ print("# New %d-ary node: %s = %p\n", n, name, nd);
+
+ nd->own_string = 0;
+ nd->prev = NULL;
+ nd->next = nodes;
+ if (nodes) {
+ nodes->prev = nd;
+ }
+ nodes = nd;
+
+ nd->name = name;
+ nd->n_elems = n;
+
+ va_start(ap, n);
+ while (i < n) {
+ nn = va_arg(ap, struct node *);
+ print("# arg[%d]: %p\n", i, nn);
+ print("# (%s ...)\n", nn->name);
+ nd->elems[i++] = nn;
+ }
+ va_end(ap);
+ n_nodes++;
+ return nd;
+}
+
+struct node *mk_atom(char *name) {
+ struct node *nd = mk_node((char const *)strdup(name), 0);
+ nd->own_string = 1;
+ return nd;
+}
+
+struct node *mk_none() {
+ return mk_atom("");
+}
+
+struct node *ext_node(struct node *nd, int n, ...) {
+ va_list ap;
+ int i = 0, c = nd->n_elems + n;
+ unsigned sz = sizeof(struct node) + (c * sizeof(struct node *));
+ struct node *nn;
+
+ print("# Extending %d-ary node by %d nodes: %s = %p",
+ nd->n_elems, c, nd->name, nd);
+
+ if (nd->next) {
+ nd->next->prev = nd->prev;
+ }
+ if (nd->prev) {
+ nd->prev->next = nd->next;
+ }
+ nd = realloc(nd, sz);
+ nd->prev = NULL;
+ nd->next = nodes;
+ nodes->prev = nd;
+ nodes = nd;
+
+ print(" ==> %p\n", nd);
+
+ va_start(ap, n);
+ while (i < n) {
+ nn = va_arg(ap, struct node *);
+ print("# arg[%d]: %p\n", i, nn);
+ print("# (%s ...)\n", nn->name);
+ nd->elems[nd->n_elems++] = nn;
+ ++i;
+ }
+ va_end(ap);
+ return nd;
+}
+
+int const indent_step = 4;
+
+void print_indent(int depth) {
+ while (depth) {
+ if (depth-- % indent_step == 0) {
+ print("|");
+ } else {
+ print(" ");
+ }
+ }
+}
+
+void print_node(struct node *n, int depth) {
+ int i = 0;
+ print_indent(depth);
+ if (n->n_elems == 0) {
+ print("%s\n", n->name);
+ } else {
+ print("(%s\n", n->name);
+ for (i = 0; i < n->n_elems; ++i) {
+ print_node(n->elems[i], depth + indent_step);
+ }
+ print_indent(depth);
+ print(")\n");
+ }
+}
+
+int main(int argc, char **argv) {
+ if (argc == 2 && strcmp(argv[1], "-v") == 0) {
+ verbose = 1;
+ } else {
+ verbose = 0;
+ }
+ int ret = 0;
+ struct node *tmp;
+ memset(pushback, '\0', PUSHBACK_LEN);
+ ret = rsparse();
+ print("--- PARSE COMPLETE: ret:%d, n_nodes:%d ---\n", ret, n_nodes);
+ if (nodes) {
+ print_node(nodes, 0);
+ }
+ while (nodes) {
+ tmp = nodes;
+ nodes = tmp->next;
+ if (tmp->own_string) {
+ free((void*)tmp->name);
+ }
+ free(tmp);
+ }
+ return ret;
+}
+
+void rserror(char const *s) {
+ fprintf(stderr, "%s\n", s);
+}
diff --git a/src/grammar/parser-lalr.y b/src/grammar/parser-lalr.y
new file mode 100644
index 0000000000000..5585c95a5a63a
--- /dev/null
+++ b/src/grammar/parser-lalr.y
@@ -0,0 +1,1982 @@
+%{
+#define YYERROR_VERBOSE
+#define YYSTYPE struct node *
+struct node;
+extern int yylex();
+extern void yyerror(char const *s);
+extern struct node *mk_node(char const *name, int n, ...);
+extern struct node *mk_atom(char *text);
+extern struct node *mk_none();
+extern struct node *ext_node(struct node *nd, int n, ...);
+extern void push_back(char c);
+extern char *yytext;
+%}
+%debug
+
+%token SHL
+%token SHR
+%token LE
+%token EQEQ
+%token NE
+%token GE
+%token ANDAND
+%token OROR
+%token SHLEQ
+%token SHREQ
+%token MINUSEQ
+%token ANDEQ
+%token OREQ
+%token PLUSEQ
+%token STAREQ
+%token SLASHEQ
+%token CARETEQ
+%token PERCENTEQ
+%token DOTDOT
+%token DOTDOTDOT
+%token MOD_SEP
+%token RARROW
+%token LARROW
+%token FAT_ARROW
+%token LIT_BYTE
+%token LIT_CHAR
+%token LIT_INTEGER
+%token LIT_FLOAT
+%token LIT_STR
+%token LIT_STR_RAW
+%token LIT_BYTE_STR
+%token LIT_BYTE_STR_RAW
+%token IDENT
+%token UNDERSCORE
+%token LIFETIME
+
+// keywords
+%token SELF
+%token STATIC
+%token ABSTRACT
+%token ALIGNOF
+%token AS
+%token BECOME
+%token BREAK
+%token CATCH
+%token CRATE
+%token DO
+%token ELSE
+%token ENUM
+%token EXTERN
+%token FALSE
+%token FINAL
+%token FN
+%token FOR
+%token IF
+%token IMPL
+%token IN
+%token LET
+%token LOOP
+%token MACRO
+%token MATCH
+%token MOD
+%token MOVE
+%token MUT
+%token OFFSETOF
+%token OVERRIDE
+%token PRIV
+%token PUB
+%token PURE
+%token REF
+%token RETURN
+%token SIZEOF
+%token STRUCT
+%token SUPER
+%token UNION
+%token UNSIZED
+%token TRUE
+%token TRAIT
+%token TYPE
+%token UNSAFE
+%token VIRTUAL
+%token YIELD
+%token DEFAULT
+%token USE
+%token WHILE
+%token CONTINUE
+%token PROC
+%token BOX
+%token CONST
+%token WHERE
+%token TYPEOF
+%token INNER_DOC_COMMENT
+%token OUTER_DOC_COMMENT
+
+%token SHEBANG
+%token SHEBANG_LINE
+%token STATIC_LIFETIME
+
+ /*
+ Quoting from the Bison manual:
+
+ "Finally, the resolution of conflicts works by comparing the precedence
+ of the rule being considered with that of the lookahead token. If the
+ token's precedence is higher, the choice is to shift. If the rule's
+ precedence is higher, the choice is to reduce. If they have equal
+ precedence, the choice is made based on the associativity of that
+ precedence level. The verbose output file made by ‘-v’ (see Invoking
+ Bison) says how each conflict was resolved"
+ */
+
+// We expect no shift/reduce or reduce/reduce conflicts in this grammar;
+// all potential ambiguities are scrutinized and eliminated manually.
+%expect 0
+
+// fake-precedence symbol to cause '|' bars in lambda context to parse
+// at low precedence, permit things like |x| foo = bar, where '=' is
+// otherwise lower-precedence than '|'. Also used for proc() to cause
+// things like proc() a + b to parse as proc() { a + b }.
+%precedence LAMBDA
+
+%precedence SELF
+
+// MUT should be lower precedence than IDENT so that in the pat rule,
+// "& MUT pat" has higher precedence than "binding_mode ident [@ pat]"
+%precedence MUT
+
+// IDENT needs to be lower than '{' so that 'foo {' is shifted when
+// trying to decide if we've got a struct-construction expr (esp. in
+// contexts like 'if foo { .')
+//
+// IDENT also needs to be lower precedence than '<' so that '<' in
+// 'foo:bar . <' is shifted (in a trait reference occurring in a
+// bounds list), parsing as foo:(bar) rather than (foo:bar).
+%precedence IDENT
+ // Put the weak keywords that can be used as idents here as well
+%precedence CATCH
+%precedence DEFAULT
+%precedence UNION
+
+// A couple fake-precedence symbols to use in rules associated with +
+// and < in trailing type contexts. These come up when you have a type
+// in the RHS of operator-AS, such as "foo as bar". The "<" there
+// has to be shifted so the parser keeps trying to parse a type, even
+// though it might well consider reducing the type "bar" and then
+// going on to "<" as a subsequent binop. The "+" case is with
+// trailing type-bounds ("foo as bar:A+B"), for the same reason.
+%precedence SHIFTPLUS
+
+%precedence MOD_SEP
+%precedence RARROW ':'
+
+// In where clauses, "for" should have greater precedence when used as
+// a higher ranked constraint than when used as the beginning of a
+// for_in_type (which is a ty)
+%precedence FORTYPE
+%precedence FOR
+
+// Binops & unops, and their precedences
+%precedence '?'
+%precedence BOX
+%nonassoc DOTDOT
+
+// RETURN needs to be lower-precedence than tokens that start
+// prefix_exprs
+%precedence RETURN YIELD
+
+%right '=' SHLEQ SHREQ MINUSEQ ANDEQ OREQ PLUSEQ STAREQ SLASHEQ CARETEQ PERCENTEQ
+%right LARROW
+%left OROR
+%left ANDAND
+%left EQEQ NE
+%left '<' '>' LE GE
+%left '|'
+%left '^'
+%left '&'
+%left SHL SHR
+%left '+' '-'
+%precedence AS
+%left '*' '/' '%'
+%precedence '!'
+
+%precedence '{' '[' '(' '.'
+
+%precedence RANGE
+
+%start crate
+
+%%
+
+////////////////////////////////////////////////////////////////////////
+// Part 1: Items and attributes
+////////////////////////////////////////////////////////////////////////
+
+crate
+: maybe_shebang inner_attrs maybe_mod_items { mk_node("crate", 2, $2, $3); }
+| maybe_shebang maybe_mod_items { mk_node("crate", 1, $2); }
+;
+
+maybe_shebang
+: SHEBANG_LINE
+| %empty
+;
+
+maybe_inner_attrs
+: inner_attrs
+| %empty { $$ = mk_none(); }
+;
+
+inner_attrs
+: inner_attr { $$ = mk_node("InnerAttrs", 1, $1); }
+| inner_attrs inner_attr { $$ = ext_node($1, 1, $2); }
+;
+
+inner_attr
+: SHEBANG '[' meta_item ']' { $$ = mk_node("InnerAttr", 1, $3); }
+| INNER_DOC_COMMENT { $$ = mk_node("InnerAttr", 1, mk_node("doc-comment", 1, mk_atom(yytext))); }
+;
+
+maybe_outer_attrs
+: outer_attrs
+| %empty { $$ = mk_none(); }
+;
+
+outer_attrs
+: outer_attr { $$ = mk_node("OuterAttrs", 1, $1); }
+| outer_attrs outer_attr { $$ = ext_node($1, 1, $2); }
+;
+
+outer_attr
+: '#' '[' meta_item ']' { $$ = $3; }
+| OUTER_DOC_COMMENT { $$ = mk_node("doc-comment", 1, mk_atom(yytext)); }
+;
+
+meta_item
+: ident { $$ = mk_node("MetaWord", 1, $1); }
+| ident '=' lit { $$ = mk_node("MetaNameValue", 2, $1, $3); }
+| ident '(' meta_seq ')' { $$ = mk_node("MetaList", 2, $1, $3); }
+| ident '(' meta_seq ',' ')' { $$ = mk_node("MetaList", 2, $1, $3); }
+;
+
+meta_seq
+: %empty { $$ = mk_none(); }
+| meta_item { $$ = mk_node("MetaItems", 1, $1); }
+| meta_seq ',' meta_item { $$ = ext_node($1, 1, $3); }
+;
+
+maybe_mod_items
+: mod_items
+| %empty { $$ = mk_none(); }
+;
+
+mod_items
+: mod_item { $$ = mk_node("Items", 1, $1); }
+| mod_items mod_item { $$ = ext_node($1, 1, $2); }
+;
+
+attrs_and_vis
+: maybe_outer_attrs visibility { $$ = mk_node("AttrsAndVis", 2, $1, $2); }
+;
+
+mod_item
+: attrs_and_vis item { $$ = mk_node("Item", 2, $1, $2); }
+;
+
+// items that can appear outside of a fn block
+item
+: stmt_item
+| item_macro
+;
+
+// items that can appear in "stmts"
+stmt_item
+: item_static
+| item_const
+| item_type
+| block_item
+| view_item
+;
+
+item_static
+: STATIC ident ':' ty '=' expr ';' { $$ = mk_node("ItemStatic", 3, $2, $4, $6); }
+| STATIC MUT ident ':' ty '=' expr ';' { $$ = mk_node("ItemStatic", 3, $3, $5, $7); }
+;
+
+item_const
+: CONST ident ':' ty '=' expr ';' { $$ = mk_node("ItemConst", 3, $2, $4, $6); }
+;
+
+item_macro
+: path_expr '!' maybe_ident parens_delimited_token_trees ';' { $$ = mk_node("ItemMacro", 3, $1, $3, $4); }
+| path_expr '!' maybe_ident braces_delimited_token_trees { $$ = mk_node("ItemMacro", 3, $1, $3, $4); }
+| path_expr '!' maybe_ident brackets_delimited_token_trees ';'{ $$ = mk_node("ItemMacro", 3, $1, $3, $4); }
+;
+
+view_item
+: use_item
+| extern_fn_item
+| EXTERN CRATE ident ';' { $$ = mk_node("ViewItemExternCrate", 1, $3); }
+| EXTERN CRATE ident AS ident ';' { $$ = mk_node("ViewItemExternCrate", 2, $3, $5); }
+;
+
+extern_fn_item
+: EXTERN maybe_abi item_fn { $$ = mk_node("ViewItemExternFn", 2, $2, $3); }
+;
+
+use_item
+: USE view_path ';' { $$ = mk_node("ViewItemUse", 1, $2); }
+;
+
+view_path
+: path_no_types_allowed { $$ = mk_node("ViewPathSimple", 1, $1); }
+| path_no_types_allowed MOD_SEP '{' '}' { $$ = mk_node("ViewPathList", 2, $1, mk_atom("ViewPathListEmpty")); }
+| MOD_SEP '{' '}' { $$ = mk_node("ViewPathList", 1, mk_atom("ViewPathListEmpty")); }
+| path_no_types_allowed MOD_SEP '{' idents_or_self '}' { $$ = mk_node("ViewPathList", 2, $1, $4); }
+| MOD_SEP '{' idents_or_self '}' { $$ = mk_node("ViewPathList", 1, $3); }
+| path_no_types_allowed MOD_SEP '{' idents_or_self ',' '}' { $$ = mk_node("ViewPathList", 2, $1, $4); }
+| MOD_SEP '{' idents_or_self ',' '}' { $$ = mk_node("ViewPathList", 1, $3); }
+| path_no_types_allowed MOD_SEP '*' { $$ = mk_node("ViewPathGlob", 1, $1); }
+| MOD_SEP '*' { $$ = mk_atom("ViewPathGlob"); }
+| '*' { $$ = mk_atom("ViewPathGlob"); }
+| '{' '}' { $$ = mk_atom("ViewPathListEmpty"); }
+| '{' idents_or_self '}' { $$ = mk_node("ViewPathList", 1, $2); }
+| '{' idents_or_self ',' '}' { $$ = mk_node("ViewPathList", 1, $2); }
+| path_no_types_allowed AS ident { $$ = mk_node("ViewPathSimple", 2, $1, $3); }
+;
+
+block_item
+: item_fn
+| item_unsafe_fn
+| item_mod
+| item_foreign_mod { $$ = mk_node("ItemForeignMod", 1, $1); }
+| item_struct
+| item_enum
+| item_union
+| item_trait
+| item_impl
+;
+
+maybe_ty_ascription
+: ':' ty_sum { $$ = $2; }
+| %empty { $$ = mk_none(); }
+;
+
+maybe_init_expr
+: '=' expr { $$ = $2; }
+| %empty { $$ = mk_none(); }
+;
+
+// structs
+item_struct
+: STRUCT ident generic_params maybe_where_clause struct_decl_args
+{
+ $$ = mk_node("ItemStruct", 4, $2, $3, $4, $5);
+}
+| STRUCT ident generic_params struct_tuple_args maybe_where_clause ';'
+{
+ $$ = mk_node("ItemStruct", 4, $2, $3, $4, $5);
+}
+| STRUCT ident generic_params maybe_where_clause ';'
+{
+ $$ = mk_node("ItemStruct", 3, $2, $3, $4);
+}
+;
+
+struct_decl_args
+: '{' struct_decl_fields '}' { $$ = $2; }
+| '{' struct_decl_fields ',' '}' { $$ = $2; }
+;
+
+struct_tuple_args
+: '(' struct_tuple_fields ')' { $$ = $2; }
+| '(' struct_tuple_fields ',' ')' { $$ = $2; }
+;
+
+struct_decl_fields
+: struct_decl_field { $$ = mk_node("StructFields", 1, $1); }
+| struct_decl_fields ',' struct_decl_field { $$ = ext_node($1, 1, $3); }
+| %empty { $$ = mk_none(); }
+;
+
+struct_decl_field
+: attrs_and_vis ident ':' ty_sum { $$ = mk_node("StructField", 3, $1, $2, $4); }
+;
+
+struct_tuple_fields
+: struct_tuple_field { $$ = mk_node("StructFields", 1, $1); }
+| struct_tuple_fields ',' struct_tuple_field { $$ = ext_node($1, 1, $3); }
+| %empty { $$ = mk_none(); }
+;
+
+struct_tuple_field
+: attrs_and_vis ty_sum { $$ = mk_node("StructField", 2, $1, $2); }
+;
+
+// enums
+item_enum
+: ENUM ident generic_params maybe_where_clause '{' enum_defs '}' { $$ = mk_node("ItemEnum", 0); }
+| ENUM ident generic_params maybe_where_clause '{' enum_defs ',' '}' { $$ = mk_node("ItemEnum", 0); }
+;
+
+enum_defs
+: enum_def { $$ = mk_node("EnumDefs", 1, $1); }
+| enum_defs ',' enum_def { $$ = ext_node($1, 1, $3); }
+| %empty { $$ = mk_none(); }
+;
+
+enum_def
+: attrs_and_vis ident enum_args { $$ = mk_node("EnumDef", 3, $1, $2, $3); }
+;
+
+enum_args
+: '{' struct_decl_fields '}' { $$ = mk_node("EnumArgs", 1, $2); }
+| '{' struct_decl_fields ',' '}' { $$ = mk_node("EnumArgs", 1, $2); }
+| '(' maybe_ty_sums ')' { $$ = mk_node("EnumArgs", 1, $2); }
+| '=' expr { $$ = mk_node("EnumArgs", 1, $2); }
+| %empty { $$ = mk_none(); }
+;
+
+// unions
+item_union
+: UNION ident generic_params maybe_where_clause '{' struct_decl_fields '}' { $$ = mk_node("ItemUnion", 0); }
+| UNION ident generic_params maybe_where_clause '{' struct_decl_fields ',' '}' { $$ = mk_node("ItemUnion", 0); }
+
+item_mod
+: MOD ident ';' { $$ = mk_node("ItemMod", 1, $2); }
+| MOD ident '{' maybe_mod_items '}' { $$ = mk_node("ItemMod", 2, $2, $4); }
+| MOD ident '{' inner_attrs maybe_mod_items '}' { $$ = mk_node("ItemMod", 3, $2, $4, $5); }
+;
+
+item_foreign_mod
+: EXTERN maybe_abi '{' maybe_foreign_items '}' { $$ = mk_node("ItemForeignMod", 1, $4); }
+| EXTERN maybe_abi '{' inner_attrs maybe_foreign_items '}' { $$ = mk_node("ItemForeignMod", 2, $4, $5); }
+;
+
+maybe_abi
+: str
+| %empty { $$ = mk_none(); }
+;
+
+maybe_foreign_items
+: foreign_items
+| %empty { $$ = mk_none(); }
+;
+
+foreign_items
+: foreign_item { $$ = mk_node("ForeignItems", 1, $1); }
+| foreign_items foreign_item { $$ = ext_node($1, 1, $2); }
+;
+
+foreign_item
+: attrs_and_vis STATIC item_foreign_static { $$ = mk_node("ForeignItem", 2, $1, $3); }
+| attrs_and_vis item_foreign_fn { $$ = mk_node("ForeignItem", 2, $1, $2); }
+| attrs_and_vis UNSAFE item_foreign_fn { $$ = mk_node("ForeignItem", 2, $1, $3); }
+;
+
+item_foreign_static
+: maybe_mut ident ':' ty ';' { $$ = mk_node("StaticItem", 3, $1, $2, $4); }
+;
+
+item_foreign_fn
+: FN ident generic_params fn_decl_allow_variadic maybe_where_clause ';' { $$ = mk_node("ForeignFn", 4, $2, $3, $4, $5); }
+;
+
+fn_decl_allow_variadic
+: fn_params_allow_variadic ret_ty { $$ = mk_node("FnDecl", 2, $1, $2); }
+;
+
+fn_params_allow_variadic
+: '(' ')' { $$ = mk_none(); }
+| '(' params ')' { $$ = $2; }
+| '(' params ',' ')' { $$ = $2; }
+| '(' params ',' DOTDOTDOT ')' { $$ = $2; }
+;
+
+visibility
+: PUB { $$ = mk_atom("Public"); }
+| %empty { $$ = mk_atom("Inherited"); }
+;
+
+idents_or_self
+: ident_or_self { $$ = mk_node("IdentsOrSelf", 1, $1); }
+| idents_or_self AS ident { $$ = mk_node("IdentsOrSelf", 2, $1, $3); }
+| idents_or_self ',' ident_or_self { $$ = ext_node($1, 1, $3); }
+;
+
+ident_or_self
+: ident
+| SELF { $$ = mk_atom(yytext); }
+;
+
+item_type
+: TYPE ident generic_params maybe_where_clause '=' ty_sum ';' { $$ = mk_node("ItemTy", 4, $2, $3, $4, $6); }
+;
+
+for_sized
+: FOR '?' ident { $$ = mk_node("ForSized", 1, $3); }
+| FOR ident '?' { $$ = mk_node("ForSized", 1, $2); }
+| %empty { $$ = mk_none(); }
+;
+
+item_trait
+: maybe_unsafe TRAIT ident generic_params for_sized maybe_ty_param_bounds maybe_where_clause '{' maybe_trait_items '}'
+{
+ $$ = mk_node("ItemTrait", 7, $1, $3, $4, $5, $6, $7, $9);
+}
+;
+
+maybe_trait_items
+: trait_items
+| %empty { $$ = mk_none(); }
+;
+
+trait_items
+: trait_item { $$ = mk_node("TraitItems", 1, $1); }
+| trait_items trait_item { $$ = ext_node($1, 1, $2); }
+;
+
+trait_item
+: trait_const
+| trait_type
+| trait_method
+| maybe_outer_attrs item_macro { $$ = mk_node("TraitMacroItem", 2, $1, $2); }
+;
+
+trait_const
+: maybe_outer_attrs CONST ident maybe_ty_ascription maybe_const_default ';' { $$ = mk_node("ConstTraitItem", 4, $1, $3, $4, $5); }
+;
+
+maybe_const_default
+: '=' expr { $$ = mk_node("ConstDefault", 1, $2); }
+| %empty { $$ = mk_none(); }
+;
+
+trait_type
+: maybe_outer_attrs TYPE ty_param ';' { $$ = mk_node("TypeTraitItem", 2, $1, $3); }
+;
+
+maybe_unsafe
+: UNSAFE { $$ = mk_atom("Unsafe"); }
+| %empty { $$ = mk_none(); }
+;
+
+maybe_default_maybe_unsafe
+: DEFAULT UNSAFE { $$ = mk_atom("DefaultUnsafe"); }
+| DEFAULT { $$ = mk_atom("Default"); }
+| UNSAFE { $$ = mk_atom("Unsafe"); }
+| %empty { $$ = mk_none(); }
+
+trait_method
+: type_method { $$ = mk_node("Required", 1, $1); }
+| method { $$ = mk_node("Provided", 1, $1); }
+;
+
+type_method
+: maybe_outer_attrs maybe_unsafe FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause ';'
+{
+ $$ = mk_node("TypeMethod", 6, $1, $2, $4, $5, $6, $7);
+}
+| maybe_outer_attrs CONST maybe_unsafe FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause ';'
+{
+ $$ = mk_node("TypeMethod", 6, $1, $3, $5, $6, $7, $8);
+}
+| maybe_outer_attrs maybe_unsafe EXTERN maybe_abi FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause ';'
+{
+ $$ = mk_node("TypeMethod", 7, $1, $2, $4, $6, $7, $8, $9);
+}
+;
+
+method
+: maybe_outer_attrs maybe_unsafe FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause inner_attrs_and_block
+{
+ $$ = mk_node("Method", 7, $1, $2, $4, $5, $6, $7, $8);
+}
+| maybe_outer_attrs CONST maybe_unsafe FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause inner_attrs_and_block
+{
+ $$ = mk_node("Method", 7, $1, $3, $5, $6, $7, $8, $9);
+}
+| maybe_outer_attrs maybe_unsafe EXTERN maybe_abi FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause inner_attrs_and_block
+{
+ $$ = mk_node("Method", 8, $1, $2, $4, $6, $7, $8, $9, $10);
+}
+;
+
+impl_method
+: attrs_and_vis maybe_default maybe_unsafe FN ident generic_params fn_decl_with_self maybe_where_clause inner_attrs_and_block
+{
+ $$ = mk_node("Method", 8, $1, $2, $3, $5, $6, $7, $8, $9);
+}
+| attrs_and_vis maybe_default CONST maybe_unsafe FN ident generic_params fn_decl_with_self maybe_where_clause inner_attrs_and_block
+{
+ $$ = mk_node("Method", 8, $1, $2, $4, $6, $7, $8, $9, $10);
+}
+| attrs_and_vis maybe_default maybe_unsafe EXTERN maybe_abi FN ident generic_params fn_decl_with_self maybe_where_clause inner_attrs_and_block
+{
+ $$ = mk_node("Method", 9, $1, $2, $3, $5, $7, $8, $9, $10, $11);
+}
+;
+
+// There are two forms of impl:
+//
+// impl (<...>)? TY { ... }
+// impl (<...>)? TRAIT for TY { ... }
+//
+// Unfortunately since TY can begin with '<' itself -- as part of a
+// TyQualifiedPath type -- there's an s/r conflict when we see '<' after IMPL:
+// should we reduce one of the early rules of TY (such as maybe_once)
+// or shall we continue shifting into the generic_params list for the
+// impl?
+//
+// The production parser disambiguates a different case here by
+// permitting / requiring the user to provide parens around types when
+// they are ambiguous with traits. We do the same here, regrettably,
+// by splitting ty into ty and ty_prim.
+item_impl
+: maybe_default_maybe_unsafe IMPL generic_params ty_prim_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
+{
+ $$ = mk_node("ItemImpl", 6, $1, $3, $4, $5, $7, $8);
+}
+| maybe_default_maybe_unsafe IMPL generic_params '(' ty ')' maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
+{
+ $$ = mk_node("ItemImpl", 6, $1, $3, 5, $6, $9, $10);
+}
+| maybe_default_maybe_unsafe IMPL generic_params trait_ref FOR ty_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
+{
+ $$ = mk_node("ItemImpl", 6, $3, $4, $6, $7, $9, $10);
+}
+| maybe_default_maybe_unsafe IMPL generic_params '!' trait_ref FOR ty_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
+{
+ $$ = mk_node("ItemImplNeg", 7, $1, $3, $5, $7, $8, $10, $11);
+}
+| maybe_default_maybe_unsafe IMPL generic_params trait_ref FOR DOTDOT '{' '}'
+{
+ $$ = mk_node("ItemImplDefault", 3, $1, $3, $4);
+}
+| maybe_default_maybe_unsafe IMPL generic_params '!' trait_ref FOR DOTDOT '{' '}'
+{
+ $$ = mk_node("ItemImplDefaultNeg", 3, $1, $3, $4);
+}
+;
+
+maybe_impl_items
+: impl_items
+| %empty { $$ = mk_none(); }
+;
+
+impl_items
+: impl_item { $$ = mk_node("ImplItems", 1, $1); }
+| impl_item impl_items { $$ = ext_node($1, 1, $2); }
+;
+
+impl_item
+: impl_method
+| attrs_and_vis item_macro { $$ = mk_node("ImplMacroItem", 2, $1, $2); }
+| impl_const
+| impl_type
+;
+
+maybe_default
+: DEFAULT { $$ = mk_atom("Default"); }
+| %empty { $$ = mk_none(); }
+;
+
+impl_const
+: attrs_and_vis maybe_default item_const { $$ = mk_node("ImplConst", 3, $1, $2, $3); }
+;
+
+impl_type
+: attrs_and_vis maybe_default TYPE ident generic_params '=' ty_sum ';' { $$ = mk_node("ImplType", 5, $1, $2, $4, $5, $7); }
+;
+
+item_fn
+: FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
+{
+ $$ = mk_node("ItemFn", 5, $2, $3, $4, $5, $6);
+}
+| CONST FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
+{
+ $$ = mk_node("ItemFn", 5, $3, $4, $5, $6, $7);
+}
+;
+
+item_unsafe_fn
+: UNSAFE FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
+{
+ $$ = mk_node("ItemUnsafeFn", 5, $3, $4, $5, $6, $7);
+}
+| CONST UNSAFE FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
+{
+ $$ = mk_node("ItemUnsafeFn", 5, $4, $5, $6, $7, $8);
+}
+| UNSAFE EXTERN maybe_abi FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
+{
+ $$ = mk_node("ItemUnsafeFn", 6, $3, $5, $6, $7, $8, $9);
+}
+;
+
+fn_decl
+: fn_params ret_ty { $$ = mk_node("FnDecl", 2, $1, $2); }
+;
+
+fn_decl_with_self
+: fn_params_with_self ret_ty { $$ = mk_node("FnDecl", 2, $1, $2); }
+;
+
+fn_decl_with_self_allow_anon_params
+: fn_anon_params_with_self ret_ty { $$ = mk_node("FnDecl", 2, $1, $2); }
+;
+
+fn_params
+: '(' maybe_params ')' { $$ = $2; }
+;
+
+fn_anon_params
+: '(' anon_param anon_params_allow_variadic_tail ')' { $$ = ext_node($2, 1, $3); }
+| '(' ')' { $$ = mk_none(); }
+;
+
+fn_params_with_self
+: '(' maybe_mut SELF maybe_ty_ascription maybe_comma_params ')' { $$ = mk_node("SelfLower", 3, $2, $4, $5); }
+| '(' '&' maybe_mut SELF maybe_ty_ascription maybe_comma_params ')' { $$ = mk_node("SelfRegion", 3, $3, $5, $6); }
+| '(' '&' lifetime maybe_mut SELF maybe_ty_ascription maybe_comma_params ')' { $$ = mk_node("SelfRegion", 4, $3, $4, $6, $7); }
+| '(' maybe_params ')' { $$ = mk_node("SelfStatic", 1, $2); }
+;
+
+fn_anon_params_with_self
+: '(' maybe_mut SELF maybe_ty_ascription maybe_comma_anon_params ')' { $$ = mk_node("SelfLower", 3, $2, $4, $5); }
+| '(' '&' maybe_mut SELF maybe_ty_ascription maybe_comma_anon_params ')' { $$ = mk_node("SelfRegion", 3, $3, $5, $6); }
+| '(' '&' lifetime maybe_mut SELF maybe_ty_ascription maybe_comma_anon_params ')' { $$ = mk_node("SelfRegion", 4, $3, $4, $6, $7); }
+| '(' maybe_anon_params ')' { $$ = mk_node("SelfStatic", 1, $2); }
+;
+
+maybe_params
+: params
+| params ','
+| %empty { $$ = mk_none(); }
+;
+
+params
+: param { $$ = mk_node("Args", 1, $1); }
+| params ',' param { $$ = ext_node($1, 1, $3); }
+;
+
+param
+: pat ':' ty_sum { $$ = mk_node("Arg", 2, $1, $3); }
+;
+
+inferrable_params
+: inferrable_param { $$ = mk_node("InferrableParams", 1, $1); }
+| inferrable_params ',' inferrable_param { $$ = ext_node($1, 1, $3); }
+;
+
+inferrable_param
+: pat maybe_ty_ascription { $$ = mk_node("InferrableParam", 2, $1, $2); }
+;
+
+maybe_comma_params
+: ',' { $$ = mk_none(); }
+| ',' params { $$ = $2; }
+| ',' params ',' { $$ = $2; }
+| %empty { $$ = mk_none(); }
+;
+
+maybe_comma_anon_params
+: ',' { $$ = mk_none(); }
+| ',' anon_params { $$ = $2; }
+| ',' anon_params ',' { $$ = $2; }
+| %empty { $$ = mk_none(); }
+;
+
+maybe_anon_params
+: anon_params
+| anon_params ','
+| %empty { $$ = mk_none(); }
+;
+
+anon_params
+: anon_param { $$ = mk_node("Args", 1, $1); }
+| anon_params ',' anon_param { $$ = ext_node($1, 1, $3); }
+;
+
+// anon means it's allowed to be anonymous (type-only), but it can
+// still have a name
+anon_param
+: named_arg ':' ty { $$ = mk_node("Arg", 2, $1, $3); }
+| ty
+;
+
+anon_params_allow_variadic_tail
+: ',' DOTDOTDOT { $$ = mk_none(); }
+| ',' anon_param anon_params_allow_variadic_tail { $$ = mk_node("Args", 2, $2, $3); }
+| %empty { $$ = mk_none(); }
+;
+
+named_arg
+: ident
+| UNDERSCORE { $$ = mk_atom("PatWild"); }
+| '&' ident { $$ = $2; }
+| '&' UNDERSCORE { $$ = mk_atom("PatWild"); }
+| ANDAND ident { $$ = $2; }
+| ANDAND UNDERSCORE { $$ = mk_atom("PatWild"); }
+| MUT ident { $$ = $2; }
+;
+
+ret_ty
+: RARROW '!' { $$ = mk_none(); }
+| RARROW ty { $$ = mk_node("ret-ty", 1, $2); }
+| %prec IDENT %empty { $$ = mk_none(); }
+;
+
+generic_params
+: '<' '>' { $$ = mk_node("Generics", 2, mk_none(), mk_none()); }
+| '<' lifetimes '>' { $$ = mk_node("Generics", 2, $2, mk_none()); }
+| '<' lifetimes ',' '>' { $$ = mk_node("Generics", 2, $2, mk_none()); }
+| '<' lifetimes SHR { push_back('>'); $$ = mk_node("Generics", 2, $2, mk_none()); }
+| '<' lifetimes ',' SHR { push_back('>'); $$ = mk_node("Generics", 2, $2, mk_none()); }
+| '<' lifetimes ',' ty_params '>' { $$ = mk_node("Generics", 2, $2, $4); }
+| '<' lifetimes ',' ty_params ',' '>' { $$ = mk_node("Generics", 2, $2, $4); }
+| '<' lifetimes ',' ty_params SHR { push_back('>'); $$ = mk_node("Generics", 2, $2, $4); }
+| '<' lifetimes ',' ty_params ',' SHR { push_back('>'); $$ = mk_node("Generics", 2, $2, $4); }
+| '<' ty_params '>' { $$ = mk_node("Generics", 2, mk_none(), $2); }
+| '<' ty_params ',' '>' { $$ = mk_node("Generics", 2, mk_none(), $2); }
+| '<' ty_params SHR { push_back('>'); $$ = mk_node("Generics", 2, mk_none(), $2); }
+| '<' ty_params ',' SHR { push_back('>'); $$ = mk_node("Generics", 2, mk_none(), $2); }
+| %empty { $$ = mk_none(); }
+;
+
+maybe_where_clause
+: %empty { $$ = mk_none(); }
+| where_clause
+;
+
+where_clause
+: WHERE where_predicates { $$ = mk_node("WhereClause", 1, $2); }
+| WHERE where_predicates ',' { $$ = mk_node("WhereClause", 1, $2); }
+;
+
+where_predicates
+: where_predicate { $$ = mk_node("WherePredicates", 1, $1); }
+| where_predicates ',' where_predicate { $$ = ext_node($1, 1, $3); }
+;
+
+where_predicate
+: maybe_for_lifetimes lifetime ':' bounds { $$ = mk_node("WherePredicate", 3, $1, $2, $4); }
+| maybe_for_lifetimes ty ':' ty_param_bounds { $$ = mk_node("WherePredicate", 3, $1, $2, $4); }
+;
+
+maybe_for_lifetimes
+: FOR '<' lifetimes '>' { $$ = mk_none(); }
+| %prec FORTYPE %empty { $$ = mk_none(); }
+
+ty_params
+: ty_param { $$ = mk_node("TyParams", 1, $1); }
+| ty_params ',' ty_param { $$ = ext_node($1, 1, $3); }
+;
+
+// A path with no type parameters; e.g. `foo::bar::Baz`
+//
+// These show up in 'use' view-items, because these are processed
+// without respect to types.
+path_no_types_allowed
+: ident { $$ = mk_node("ViewPath", 1, $1); }
+| MOD_SEP ident { $$ = mk_node("ViewPath", 1, $2); }
+| SELF { $$ = mk_node("ViewPath", 1, mk_atom("Self")); }
+| MOD_SEP SELF { $$ = mk_node("ViewPath", 1, mk_atom("Self")); }
+| SUPER { $$ = mk_node("ViewPath", 1, mk_atom("Super")); }
+| MOD_SEP SUPER { $$ = mk_node("ViewPath", 1, mk_atom("Super")); }
+| path_no_types_allowed MOD_SEP ident { $$ = ext_node($1, 1, $3); }
+;
+
+// A path with a lifetime and type parameters, with no double colons
+// before the type parameters; e.g. `foo::bar<'a>::Baz`
+//
+// These show up in "trait references", the components of
+// type-parameter bounds lists, as well as in the prefix of the
+// path_generic_args_and_bounds rule, which is the full form of a
+// named typed expression.
+//
+// They do not have (nor need) an extra '::' before '<' because
+// unlike in expr context, there are no "less-than" type exprs to
+// be ambiguous with.
+path_generic_args_without_colons
+: %prec IDENT
+ ident { $$ = mk_node("components", 1, $1); }
+| %prec IDENT
+ ident generic_args { $$ = mk_node("components", 2, $1, $2); }
+| %prec IDENT
+ ident '(' maybe_ty_sums ')' ret_ty { $$ = mk_node("components", 2, $1, $3); }
+| %prec IDENT
+ path_generic_args_without_colons MOD_SEP ident { $$ = ext_node($1, 1, $3); }
+| %prec IDENT
+ path_generic_args_without_colons MOD_SEP ident generic_args { $$ = ext_node($1, 2, $3, $4); }
+| %prec IDENT
+ path_generic_args_without_colons MOD_SEP ident '(' maybe_ty_sums ')' ret_ty { $$ = ext_node($1, 2, $3, $5); }
+;
+
+generic_args
+: '<' generic_values '>' { $$ = $2; }
+| '<' generic_values SHR { push_back('>'); $$ = $2; }
+| '<' generic_values GE { push_back('='); $$ = $2; }
+| '<' generic_values SHREQ { push_back('>'); push_back('='); $$ = $2; }
+// If generic_args starts with "<<", the first arg must be a
+// TyQualifiedPath because that's the only type that can start with a
+// '<'. This rule parses that as the first ty_sum and then continues
+// with the rest of generic_values.
+| SHL ty_qualified_path_and_generic_values '>' { $$ = $2; }
+| SHL ty_qualified_path_and_generic_values SHR { push_back('>'); $$ = $2; }
+| SHL ty_qualified_path_and_generic_values GE { push_back('='); $$ = $2; }
+| SHL ty_qualified_path_and_generic_values SHREQ { push_back('>'); push_back('='); $$ = $2; }
+;
+
+generic_values
+: maybe_ty_sums_and_or_bindings { $$ = mk_node("GenericValues", 1, $1); }
+;
+
+maybe_ty_sums_and_or_bindings
+: ty_sums
+| ty_sums ','
+| ty_sums ',' bindings { $$ = mk_node("TySumsAndBindings", 2, $1, $3); }
+| bindings
+| bindings ','
+| %empty { $$ = mk_none(); }
+;
+
+maybe_bindings
+: ',' bindings { $$ = $2; }
+| %empty { $$ = mk_none(); }
+;
+
+////////////////////////////////////////////////////////////////////////
+// Part 2: Patterns
+////////////////////////////////////////////////////////////////////////
+
+pat
+: UNDERSCORE { $$ = mk_atom("PatWild"); }
+| '&' pat { $$ = mk_node("PatRegion", 1, $2); }
+| '&' MUT pat { $$ = mk_node("PatRegion", 1, $3); }
+| ANDAND pat { $$ = mk_node("PatRegion", 1, mk_node("PatRegion", 1, $2)); }
+| '(' ')' { $$ = mk_atom("PatUnit"); }
+| '(' pat_tup ')' { $$ = mk_node("PatTup", 1, $2); }
+| '[' pat_vec ']' { $$ = mk_node("PatVec", 1, $2); }
+| lit_or_path
+| lit_or_path DOTDOTDOT lit_or_path { $$ = mk_node("PatRange", 2, $1, $3); }
+| path_expr '{' pat_struct '}' { $$ = mk_node("PatStruct", 2, $1, $3); }
+| path_expr '(' ')' { $$ = mk_node("PatEnum", 2, $1, mk_none()); }
+| path_expr '(' pat_tup ')' { $$ = mk_node("PatEnum", 2, $1, $3); }
+| path_expr '!' maybe_ident delimited_token_trees { $$ = mk_node("PatMac", 3, $1, $3, $4); }
+| binding_mode ident { $$ = mk_node("PatIdent", 2, $1, $2); }
+| ident '@' pat { $$ = mk_node("PatIdent", 3, mk_node("BindByValue", 1, mk_atom("MutImmutable")), $1, $3); }
+| binding_mode ident '@' pat { $$ = mk_node("PatIdent", 3, $1, $2, $4); }
+| BOX pat { $$ = mk_node("PatUniq", 1, $2); }
+| '<' ty_sum maybe_as_trait_ref '>' MOD_SEP ident { $$ = mk_node("PatQualifiedPath", 3, $2, $3, $6); }
+| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident
+{
+ $$ = mk_node("PatQualifiedPath", 3, mk_node("PatQualifiedPath", 3, $2, $3, $6), $7, $10);
+}
+;
+
+pats_or
+: pat { $$ = mk_node("Pats", 1, $1); }
+| pats_or '|' pat { $$ = ext_node($1, 1, $3); }
+;
+
+binding_mode
+: REF { $$ = mk_node("BindByRef", 1, mk_atom("MutImmutable")); }
+| REF MUT { $$ = mk_node("BindByRef", 1, mk_atom("MutMutable")); }
+| MUT { $$ = mk_node("BindByValue", 1, mk_atom("MutMutable")); }
+;
+
+lit_or_path
+: path_expr { $$ = mk_node("PatLit", 1, $1); }
+| lit { $$ = mk_node("PatLit", 1, $1); }
+| '-' lit { $$ = mk_node("PatLit", 1, $2); }
+;
+
+pat_field
+: ident { $$ = mk_node("PatField", 1, $1); }
+| binding_mode ident { $$ = mk_node("PatField", 2, $1, $2); }
+| BOX ident { $$ = mk_node("PatField", 2, mk_atom("box"), $2); }
+| BOX binding_mode ident { $$ = mk_node("PatField", 3, mk_atom("box"), $2, $3); }
+| ident ':' pat { $$ = mk_node("PatField", 2, $1, $3); }
+| binding_mode ident ':' pat { $$ = mk_node("PatField", 3, $1, $2, $4); }
+| LIT_INTEGER ':' pat { $$ = mk_node("PatField", 2, mk_atom(yytext), $3); }
+;
+
+pat_fields
+: pat_field { $$ = mk_node("PatFields", 1, $1); }
+| pat_fields ',' pat_field { $$ = ext_node($1, 1, $3); }
+;
+
+pat_struct
+: pat_fields { $$ = mk_node("PatStruct", 2, $1, mk_atom("false")); }
+| pat_fields ',' { $$ = mk_node("PatStruct", 2, $1, mk_atom("false")); }
+| pat_fields ',' DOTDOT { $$ = mk_node("PatStruct", 2, $1, mk_atom("true")); }
+| DOTDOT { $$ = mk_node("PatStruct", 1, mk_atom("true")); }
+| %empty { $$ = mk_node("PatStruct", 1, mk_none()); }
+;
+
+pat_tup
+: pat_tup_elts { $$ = mk_node("PatTup", 2, $1, mk_none()); }
+| pat_tup_elts ',' { $$ = mk_node("PatTup", 2, $1, mk_none()); }
+| pat_tup_elts DOTDOT { $$ = mk_node("PatTup", 2, $1, mk_none()); }
+| pat_tup_elts ',' DOTDOT { $$ = mk_node("PatTup", 2, $1, mk_none()); }
+| pat_tup_elts DOTDOT ',' pat_tup_elts { $$ = mk_node("PatTup", 2, $1, $4); }
+| pat_tup_elts DOTDOT ',' pat_tup_elts ',' { $$ = mk_node("PatTup", 2, $1, $4); }
+| pat_tup_elts ',' DOTDOT ',' pat_tup_elts { $$ = mk_node("PatTup", 2, $1, $5); }
+| pat_tup_elts ',' DOTDOT ',' pat_tup_elts ',' { $$ = mk_node("PatTup", 2, $1, $5); }
+| DOTDOT ',' pat_tup_elts { $$ = mk_node("PatTup", 2, mk_none(), $3); }
+| DOTDOT ',' pat_tup_elts ',' { $$ = mk_node("PatTup", 2, mk_none(), $3); }
+| DOTDOT { $$ = mk_node("PatTup", 2, mk_none(), mk_none()); }
+;
+
+pat_tup_elts
+: pat { $$ = mk_node("PatTupElts", 1, $1); }
+| pat_tup_elts ',' pat { $$ = ext_node($1, 1, $3); }
+;
+
+pat_vec
+: pat_vec_elts { $$ = mk_node("PatVec", 2, $1, mk_none()); }
+| pat_vec_elts ',' { $$ = mk_node("PatVec", 2, $1, mk_none()); }
+| pat_vec_elts DOTDOT { $$ = mk_node("PatVec", 2, $1, mk_none()); }
+| pat_vec_elts ',' DOTDOT { $$ = mk_node("PatVec", 2, $1, mk_none()); }
+| pat_vec_elts DOTDOT ',' pat_vec_elts { $$ = mk_node("PatVec", 2, $1, $4); }
+| pat_vec_elts DOTDOT ',' pat_vec_elts ',' { $$ = mk_node("PatVec", 2, $1, $4); }
+| pat_vec_elts ',' DOTDOT ',' pat_vec_elts { $$ = mk_node("PatVec", 2, $1, $5); }
+| pat_vec_elts ',' DOTDOT ',' pat_vec_elts ',' { $$ = mk_node("PatVec", 2, $1, $5); }
+| DOTDOT ',' pat_vec_elts { $$ = mk_node("PatVec", 2, mk_none(), $3); }
+| DOTDOT ',' pat_vec_elts ',' { $$ = mk_node("PatVec", 2, mk_none(), $3); }
+| DOTDOT { $$ = mk_node("PatVec", 2, mk_none(), mk_none()); }
+| %empty { $$ = mk_node("PatVec", 2, mk_none(), mk_none()); }
+;
+
+pat_vec_elts
+: pat { $$ = mk_node("PatVecElts", 1, $1); }
+| pat_vec_elts ',' pat { $$ = ext_node($1, 1, $3); }
+;
+
+////////////////////////////////////////////////////////////////////////
+// Part 3: Types
+////////////////////////////////////////////////////////////////////////
+
+ty
+: ty_prim
+| ty_closure
+| '<' ty_sum maybe_as_trait_ref '>' MOD_SEP ident { $$ = mk_node("TyQualifiedPath", 3, $2, $3, $6); }
+| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident { $$ = mk_node("TyQualifiedPath", 3, mk_node("TyQualifiedPath", 3, $2, $3, $6), $7, $10); }
+| '(' ty_sums ')' { $$ = mk_node("TyTup", 1, $2); }
+| '(' ty_sums ',' ')' { $$ = mk_node("TyTup", 1, $2); }
+| '(' ')' { $$ = mk_atom("TyNil"); }
+;
+
+ty_prim
+: %prec IDENT path_generic_args_without_colons { $$ = mk_node("TyPath", 2, mk_node("global", 1, mk_atom("false")), $1); }
+| %prec IDENT MOD_SEP path_generic_args_without_colons { $$ = mk_node("TyPath", 2, mk_node("global", 1, mk_atom("true")), $2); }
+| %prec IDENT SELF MOD_SEP path_generic_args_without_colons { $$ = mk_node("TyPath", 2, mk_node("self", 1, mk_atom("true")), $3); }
+| %prec IDENT path_generic_args_without_colons '!' maybe_ident delimited_token_trees { $$ = mk_node("TyMacro", 3, $1, $3, $4); }
+| %prec IDENT MOD_SEP path_generic_args_without_colons '!' maybe_ident delimited_token_trees { $$ = mk_node("TyMacro", 3, $2, $4, $5); }
+| BOX ty { $$ = mk_node("TyBox", 1, $2); }
+| '*' maybe_mut_or_const ty { $$ = mk_node("TyPtr", 2, $2, $3); }
+| '&' ty { $$ = mk_node("TyRptr", 2, mk_atom("MutImmutable"), $2); }
+| '&' MUT ty { $$ = mk_node("TyRptr", 2, mk_atom("MutMutable"), $3); }
+| ANDAND ty { $$ = mk_node("TyRptr", 1, mk_node("TyRptr", 2, mk_atom("MutImmutable"), $2)); }
+| ANDAND MUT ty { $$ = mk_node("TyRptr", 1, mk_node("TyRptr", 2, mk_atom("MutMutable"), $3)); }
+| '&' lifetime maybe_mut ty { $$ = mk_node("TyRptr", 3, $2, $3, $4); }
+| ANDAND lifetime maybe_mut ty { $$ = mk_node("TyRptr", 1, mk_node("TyRptr", 3, $2, $3, $4)); }
+| '[' ty ']' { $$ = mk_node("TyVec", 1, $2); }
+| '[' ty ',' DOTDOT expr ']' { $$ = mk_node("TyFixedLengthVec", 2, $2, $5); }
+| '[' ty ';' expr ']' { $$ = mk_node("TyFixedLengthVec", 2, $2, $4); }
+| TYPEOF '(' expr ')' { $$ = mk_node("TyTypeof", 1, $3); }
+| UNDERSCORE { $$ = mk_atom("TyInfer"); }
+| ty_bare_fn
+| for_in_type
+;
+
+ty_bare_fn
+: FN ty_fn_decl { $$ = $2; }
+| UNSAFE FN ty_fn_decl { $$ = $3; }
+| EXTERN maybe_abi FN ty_fn_decl { $$ = $4; }
+| UNSAFE EXTERN maybe_abi FN ty_fn_decl { $$ = $5; }
+;
+
+ty_fn_decl
+: generic_params fn_anon_params ret_ty { $$ = mk_node("TyFnDecl", 3, $1, $2, $3); }
+;
+
+ty_closure
+: UNSAFE '|' anon_params '|' maybe_bounds ret_ty { $$ = mk_node("TyClosure", 3, $3, $5, $6); }
+| '|' anon_params '|' maybe_bounds ret_ty { $$ = mk_node("TyClosure", 3, $2, $4, $5); }
+| UNSAFE OROR maybe_bounds ret_ty { $$ = mk_node("TyClosure", 2, $3, $4); }
+| OROR maybe_bounds ret_ty { $$ = mk_node("TyClosure", 2, $2, $3); }
+;
+
+for_in_type
+: FOR '<' maybe_lifetimes '>' for_in_type_suffix { $$ = mk_node("ForInType", 2, $3, $5); }
+;
+
+for_in_type_suffix
+: ty_bare_fn
+| trait_ref
+| ty_closure
+;
+
+maybe_mut
+: MUT { $$ = mk_atom("MutMutable"); }
+| %prec MUT %empty { $$ = mk_atom("MutImmutable"); }
+;
+
+maybe_mut_or_const
+: MUT { $$ = mk_atom("MutMutable"); }
+| CONST { $$ = mk_atom("MutImmutable"); }
+| %empty { $$ = mk_atom("MutImmutable"); }
+;
+
+ty_qualified_path_and_generic_values
+: ty_qualified_path maybe_bindings
+{
+ $$ = mk_node("GenericValues", 3, mk_none(), mk_node("TySums", 1, mk_node("TySum", 1, $1)), $2);
+}
+| ty_qualified_path ',' ty_sums maybe_bindings
+{
+ $$ = mk_node("GenericValues", 3, mk_none(), mk_node("TySums", 2, $1, $3), $4);
+}
+;
+
+ty_qualified_path
+: ty_sum AS trait_ref '>' MOD_SEP ident { $$ = mk_node("TyQualifiedPath", 3, $1, $3, $6); }
+| ty_sum AS trait_ref '>' MOD_SEP ident '+' ty_param_bounds { $$ = mk_node("TyQualifiedPath", 3, $1, $3, $6); }
+;
+
+maybe_ty_sums
+: ty_sums
+| ty_sums ','
+| %empty { $$ = mk_none(); }
+;
+
+ty_sums
+: ty_sum { $$ = mk_node("TySums", 1, $1); }
+| ty_sums ',' ty_sum { $$ = ext_node($1, 1, $3); }
+;
+
+ty_sum
+: ty_sum_elt { $$ = mk_node("TySum", 1, $1); }
+| ty_sum '+' ty_sum_elt { $$ = ext_node($1, 1, $3); }
+;
+
+ty_sum_elt
+: ty
+| lifetime
+;
+
+ty_prim_sum
+: ty_prim_sum_elt { $$ = mk_node("TySum", 1, $1); }
+| ty_prim_sum '+' ty_prim_sum_elt { $$ = ext_node($1, 1, $3); }
+;
+
+ty_prim_sum_elt
+: ty_prim
+| lifetime
+;
+
+maybe_ty_param_bounds
+: ':' ty_param_bounds { $$ = $2; }
+| %empty { $$ = mk_none(); }
+;
+
+ty_param_bounds
+: boundseq
+| %empty { $$ = mk_none(); }
+;
+
+boundseq
+: polybound
+| boundseq '+' polybound { $$ = ext_node($1, 1, $3); }
+;
+
+polybound
+: FOR '<' maybe_lifetimes '>' bound { $$ = mk_node("PolyBound", 2, $3, $5); }
+| bound
+| '?' FOR '<' maybe_lifetimes '>' bound { $$ = mk_node("PolyBound", 2, $4, $6); }
+| '?' bound { $$ = $2; }
+;
+
+bindings
+: binding { $$ = mk_node("Bindings", 1, $1); }
+| bindings ',' binding { $$ = ext_node($1, 1, $3); }
+;
+
+binding
+: ident '=' ty { mk_node("Binding", 2, $1, $3); }
+;
+
+ty_param
+: ident maybe_ty_param_bounds maybe_ty_default { $$ = mk_node("TyParam", 3, $1, $2, $3); }
+| ident '?' ident maybe_ty_param_bounds maybe_ty_default { $$ = mk_node("TyParam", 4, $1, $3, $4, $5); }
+;
+
+maybe_bounds
+: %prec SHIFTPLUS
+ ':' bounds { $$ = $2; }
+| %prec SHIFTPLUS %empty { $$ = mk_none(); }
+;
+
+bounds
+: bound { $$ = mk_node("bounds", 1, $1); }
+| bounds '+' bound { $$ = ext_node($1, 1, $3); }
+;
+
+bound
+: lifetime
+| trait_ref
+;
+
+maybe_ltbounds
+: %prec SHIFTPLUS
+ ':' ltbounds { $$ = $2; }
+| %empty { $$ = mk_none(); }
+;
+
+ltbounds
+: lifetime { $$ = mk_node("ltbounds", 1, $1); }
+| ltbounds '+' lifetime { $$ = ext_node($1, 1, $3); }
+;
+
+maybe_ty_default
+: '=' ty_sum { $$ = mk_node("TyDefault", 1, $2); }
+| %empty { $$ = mk_none(); }
+;
+
+maybe_lifetimes
+: lifetimes
+| lifetimes ','
+| %empty { $$ = mk_none(); }
+;
+
+lifetimes
+: lifetime_and_bounds { $$ = mk_node("Lifetimes", 1, $1); }
+| lifetimes ',' lifetime_and_bounds { $$ = ext_node($1, 1, $3); }
+;
+
+lifetime_and_bounds
+: LIFETIME maybe_ltbounds { $$ = mk_node("lifetime", 2, mk_atom(yytext), $2); }
+| STATIC_LIFETIME { $$ = mk_atom("static_lifetime"); }
+;
+
+lifetime
+: LIFETIME { $$ = mk_node("lifetime", 1, mk_atom(yytext)); }
+| STATIC_LIFETIME { $$ = mk_atom("static_lifetime"); }
+;
+
+trait_ref
+: %prec IDENT path_generic_args_without_colons
+| %prec IDENT MOD_SEP path_generic_args_without_colons { $$ = $2; }
+;
+
+////////////////////////////////////////////////////////////////////////
+// Part 4: Blocks, statements, and expressions
+////////////////////////////////////////////////////////////////////////
+
+inner_attrs_and_block
+: '{' maybe_inner_attrs maybe_stmts '}' { $$ = mk_node("ExprBlock", 2, $2, $3); }
+;
+
+block
+: '{' maybe_stmts '}' { $$ = mk_node("ExprBlock", 1, $2); }
+;
+
+maybe_stmts
+: stmts
+| stmts nonblock_expr { $$ = ext_node($1, 1, $2); }
+| nonblock_expr
+| %empty { $$ = mk_none(); }
+;
+
+// There are two sub-grammars within a "stmts: exprs" derivation
+// depending on whether each stmt-expr is a block-expr form; this is to
+// handle the "semicolon rule" for stmt sequencing that permits
+// writing
+//
+// if foo { bar } 10
+//
+// as a sequence of two stmts (one if-expr stmt, one lit-10-expr
+// stmt). Unfortunately by permitting juxtaposition of exprs in
+// sequence like that, the non-block expr grammar has to have a
+// second limited sub-grammar that excludes the prefix exprs that
+// are ambiguous with binops. That is to say:
+//
+// {10} - 1
+//
+// should parse as (progn (progn 10) (- 1)) not (- (progn 10) 1), that
+// is to say, two statements rather than one, at least according to
+// the mainline rust parser.
+//
+// So we wind up with a 3-way split in exprs that occur in stmt lists:
+// block, nonblock-prefix, and nonblock-nonprefix.
+//
+// In non-stmts contexts, expr can relax this trichotomy.
+
+stmts
+: stmt { $$ = mk_node("stmts", 1, $1); }
+| stmts stmt { $$ = ext_node($1, 1, $2); }
+;
+
+stmt
+: maybe_outer_attrs let { $$ = $2; }
+| stmt_item
+| PUB stmt_item { $$ = $2; }
+| outer_attrs stmt_item { $$ = $2; }
+| outer_attrs PUB stmt_item { $$ = $3; }
+| full_block_expr
+| maybe_outer_attrs block { $$ = $2; }
+| nonblock_expr ';'
+| outer_attrs nonblock_expr ';' { $$ = $2; }
+| ';' { $$ = mk_none(); }
+;
+
+maybe_exprs
+: exprs
+| exprs ','
+| %empty { $$ = mk_none(); }
+;
+
+maybe_expr
+: expr
+| %empty { $$ = mk_none(); }
+;
+
+exprs
+: expr { $$ = mk_node("exprs", 1, $1); }
+| exprs ',' expr { $$ = ext_node($1, 1, $3); }
+;
+
+path_expr
+: path_generic_args_with_colons
+| MOD_SEP path_generic_args_with_colons { $$ = $2; }
+| SELF MOD_SEP path_generic_args_with_colons { $$ = mk_node("SelfPath", 1, $3); }
+;
+
+// A path with a lifetime and type parameters with double colons before
+// the type parameters; e.g. `foo::bar::<'a>::Baz::`
+//
+// These show up in expr context, in order to disambiguate from "less-than"
+// expressions.
+path_generic_args_with_colons
+: ident { $$ = mk_node("components", 1, $1); }
+| SUPER { $$ = mk_atom("Super"); }
+| path_generic_args_with_colons MOD_SEP ident { $$ = ext_node($1, 1, $3); }
+| path_generic_args_with_colons MOD_SEP SUPER { $$ = ext_node($1, 1, mk_atom("Super")); }
+| path_generic_args_with_colons MOD_SEP generic_args { $$ = ext_node($1, 1, $3); }
+;
+
+// the braces-delimited macro is a block_expr so it doesn't appear here
+macro_expr
+: path_expr '!' maybe_ident parens_delimited_token_trees { $$ = mk_node("MacroExpr", 3, $1, $3, $4); }
+| path_expr '!' maybe_ident brackets_delimited_token_trees { $$ = mk_node("MacroExpr", 3, $1, $3, $4); }
+;
+
+nonblock_expr
+: lit { $$ = mk_node("ExprLit", 1, $1); }
+| %prec IDENT
+ path_expr { $$ = mk_node("ExprPath", 1, $1); }
+| SELF { $$ = mk_node("ExprPath", 1, mk_node("ident", 1, mk_atom("self"))); }
+| macro_expr { $$ = mk_node("ExprMac", 1, $1); }
+| path_expr '{' struct_expr_fields '}' { $$ = mk_node("ExprStruct", 2, $1, $3); }
+| nonblock_expr '?' { $$ = mk_node("ExprTry", 1, $1); }
+| nonblock_expr '.' path_generic_args_with_colons { $$ = mk_node("ExprField", 2, $1, $3); }
+| nonblock_expr '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); }
+| nonblock_expr '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); }
+| nonblock_expr '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 2, $1, $3); }
+| '[' vec_expr ']' { $$ = mk_node("ExprVec", 1, $2); }
+| '(' maybe_exprs ')' { $$ = mk_node("ExprParen", 1, $2); }
+| CONTINUE { $$ = mk_node("ExprAgain", 0); }
+| CONTINUE lifetime { $$ = mk_node("ExprAgain", 1, $2); }
+| RETURN { $$ = mk_node("ExprRet", 0); }
+| RETURN expr { $$ = mk_node("ExprRet", 1, $2); }
+| BREAK { $$ = mk_node("ExprBreak", 0); }
+| BREAK lifetime { $$ = mk_node("ExprBreak", 1, $2); }
+| YIELD { $$ = mk_node("ExprYield", 0); }
+| YIELD expr { $$ = mk_node("ExprYield", 1, $2); }
+| nonblock_expr '=' expr { $$ = mk_node("ExprAssign", 2, $1, $3); }
+| nonblock_expr SHLEQ expr { $$ = mk_node("ExprAssignShl", 2, $1, $3); }
+| nonblock_expr SHREQ expr { $$ = mk_node("ExprAssignShr", 2, $1, $3); }
+| nonblock_expr MINUSEQ expr { $$ = mk_node("ExprAssignSub", 2, $1, $3); }
+| nonblock_expr ANDEQ expr { $$ = mk_node("ExprAssignBitAnd", 2, $1, $3); }
+| nonblock_expr OREQ expr { $$ = mk_node("ExprAssignBitOr", 2, $1, $3); }
+| nonblock_expr PLUSEQ expr { $$ = mk_node("ExprAssignAdd", 2, $1, $3); }
+| nonblock_expr STAREQ expr { $$ = mk_node("ExprAssignMul", 2, $1, $3); }
+| nonblock_expr SLASHEQ expr { $$ = mk_node("ExprAssignDiv", 2, $1, $3); }
+| nonblock_expr CARETEQ expr { $$ = mk_node("ExprAssignBitXor", 2, $1, $3); }
+| nonblock_expr PERCENTEQ expr { $$ = mk_node("ExprAssignRem", 2, $1, $3); }
+| nonblock_expr OROR expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiOr"), $1, $3); }
+| nonblock_expr ANDAND expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiAnd"), $1, $3); }
+| nonblock_expr EQEQ expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiEq"), $1, $3); }
+| nonblock_expr NE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiNe"), $1, $3); }
+| nonblock_expr '<' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiLt"), $1, $3); }
+| nonblock_expr '>' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiGt"), $1, $3); }
+| nonblock_expr LE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiLe"), $1, $3); }
+| nonblock_expr GE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiGe"), $1, $3); }
+| nonblock_expr '|' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitOr"), $1, $3); }
+| nonblock_expr '^' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitXor"), $1, $3); }
+| nonblock_expr '&' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitAnd"), $1, $3); }
+| nonblock_expr SHL expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiShl"), $1, $3); }
+| nonblock_expr SHR expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiShr"), $1, $3); }
+| nonblock_expr '+' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiAdd"), $1, $3); }
+| nonblock_expr '-' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiSub"), $1, $3); }
+| nonblock_expr '*' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiMul"), $1, $3); }
+| nonblock_expr '/' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiDiv"), $1, $3); }
+| nonblock_expr '%' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiRem"), $1, $3); }
+| nonblock_expr DOTDOT { $$ = mk_node("ExprRange", 2, $1, mk_none()); }
+| nonblock_expr DOTDOT expr { $$ = mk_node("ExprRange", 2, $1, $3); }
+| DOTDOT expr { $$ = mk_node("ExprRange", 2, mk_none(), $2); }
+| DOTDOT { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); }
+| nonblock_expr AS ty { $$ = mk_node("ExprCast", 2, $1, $3); }
+| nonblock_expr ':' ty { $$ = mk_node("ExprTypeAscr", 2, $1, $3); }
+| BOX expr { $$ = mk_node("ExprBox", 1, $2); }
+| expr_qualified_path
+| nonblock_prefix_expr
+;
+
+expr
+: lit { $$ = mk_node("ExprLit", 1, $1); }
+| %prec IDENT
+ path_expr { $$ = mk_node("ExprPath", 1, $1); }
+| SELF { $$ = mk_node("ExprPath", 1, mk_node("ident", 1, mk_atom("self"))); }
+| macro_expr { $$ = mk_node("ExprMac", 1, $1); }
+| path_expr '{' struct_expr_fields '}' { $$ = mk_node("ExprStruct", 2, $1, $3); }
+| expr '?' { $$ = mk_node("ExprTry", 1, $1); }
+| expr '.' path_generic_args_with_colons { $$ = mk_node("ExprField", 2, $1, $3); }
+| expr '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); }
+| expr '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); }
+| expr '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 2, $1, $3); }
+| '(' maybe_exprs ')' { $$ = mk_node("ExprParen", 1, $2); }
+| '[' vec_expr ']' { $$ = mk_node("ExprVec", 1, $2); }
+| CONTINUE { $$ = mk_node("ExprAgain", 0); }
+| CONTINUE ident { $$ = mk_node("ExprAgain", 1, $2); }
+| RETURN { $$ = mk_node("ExprRet", 0); }
+| RETURN expr { $$ = mk_node("ExprRet", 1, $2); }
+| BREAK { $$ = mk_node("ExprBreak", 0); }
+| BREAK ident { $$ = mk_node("ExprBreak", 1, $2); }
+| YIELD { $$ = mk_node("ExprYield", 0); }
+| YIELD expr { $$ = mk_node("ExprYield", 1, $2); }
+| expr '=' expr { $$ = mk_node("ExprAssign", 2, $1, $3); }
+| expr SHLEQ expr { $$ = mk_node("ExprAssignShl", 2, $1, $3); }
+| expr SHREQ expr { $$ = mk_node("ExprAssignShr", 2, $1, $3); }
+| expr MINUSEQ expr { $$ = mk_node("ExprAssignSub", 2, $1, $3); }
+| expr ANDEQ expr { $$ = mk_node("ExprAssignBitAnd", 2, $1, $3); }
+| expr OREQ expr { $$ = mk_node("ExprAssignBitOr", 2, $1, $3); }
+| expr PLUSEQ expr { $$ = mk_node("ExprAssignAdd", 2, $1, $3); }
+| expr STAREQ expr { $$ = mk_node("ExprAssignMul", 2, $1, $3); }
+| expr SLASHEQ expr { $$ = mk_node("ExprAssignDiv", 2, $1, $3); }
+| expr CARETEQ expr { $$ = mk_node("ExprAssignBitXor", 2, $1, $3); }
+| expr PERCENTEQ expr { $$ = mk_node("ExprAssignRem", 2, $1, $3); }
+| expr OROR expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiOr"), $1, $3); }
+| expr ANDAND expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiAnd"), $1, $3); }
+| expr EQEQ expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiEq"), $1, $3); }
+| expr NE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiNe"), $1, $3); }
+| expr '<' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiLt"), $1, $3); }
+| expr '>' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiGt"), $1, $3); }
+| expr LE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiLe"), $1, $3); }
+| expr GE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiGe"), $1, $3); }
+| expr '|' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitOr"), $1, $3); }
+| expr '^' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitXor"), $1, $3); }
+| expr '&' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitAnd"), $1, $3); }
+| expr SHL expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiShl"), $1, $3); }
+| expr SHR expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiShr"), $1, $3); }
+| expr '+' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiAdd"), $1, $3); }
+| expr '-' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiSub"), $1, $3); }
+| expr '*' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiMul"), $1, $3); }
+| expr '/' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiDiv"), $1, $3); }
+| expr '%' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiRem"), $1, $3); }
+| expr DOTDOT { $$ = mk_node("ExprRange", 2, $1, mk_none()); }
+| expr DOTDOT expr { $$ = mk_node("ExprRange", 2, $1, $3); }
+| DOTDOT expr { $$ = mk_node("ExprRange", 2, mk_none(), $2); }
+| DOTDOT { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); }
+| expr AS ty { $$ = mk_node("ExprCast", 2, $1, $3); }
+| expr ':' ty { $$ = mk_node("ExprTypeAscr", 2, $1, $3); }
+| BOX expr { $$ = mk_node("ExprBox", 1, $2); }
+| expr_qualified_path
+| block_expr
+| block
+| nonblock_prefix_expr
+;
+
+expr_nostruct
+: lit { $$ = mk_node("ExprLit", 1, $1); }
+| %prec IDENT
+ path_expr { $$ = mk_node("ExprPath", 1, $1); }
+| SELF { $$ = mk_node("ExprPath", 1, mk_node("ident", 1, mk_atom("self"))); }
+| macro_expr { $$ = mk_node("ExprMac", 1, $1); }
+| expr_nostruct '?' { $$ = mk_node("ExprTry", 1, $1); }
+| expr_nostruct '.' path_generic_args_with_colons { $$ = mk_node("ExprField", 2, $1, $3); }
+| expr_nostruct '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); }
+| expr_nostruct '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); }
+| expr_nostruct '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 2, $1, $3); }
+| '[' vec_expr ']' { $$ = mk_node("ExprVec", 1, $2); }
+| '(' maybe_exprs ')' { $$ = mk_node("ExprParen", 1, $2); }
+| CONTINUE { $$ = mk_node("ExprAgain", 0); }
+| CONTINUE ident { $$ = mk_node("ExprAgain", 1, $2); }
+| RETURN { $$ = mk_node("ExprRet", 0); }
+| RETURN expr { $$ = mk_node("ExprRet", 1, $2); }
+| BREAK { $$ = mk_node("ExprBreak", 0); }
+| BREAK ident { $$ = mk_node("ExprBreak", 1, $2); }
+| YIELD { $$ = mk_node("ExprYield", 0); }
+| YIELD expr { $$ = mk_node("ExprYield", 1, $2); }
+| expr_nostruct '=' expr_nostruct { $$ = mk_node("ExprAssign", 2, $1, $3); }
+| expr_nostruct SHLEQ expr_nostruct { $$ = mk_node("ExprAssignShl", 2, $1, $3); }
+| expr_nostruct SHREQ expr_nostruct { $$ = mk_node("ExprAssignShr", 2, $1, $3); }
+| expr_nostruct MINUSEQ expr_nostruct { $$ = mk_node("ExprAssignSub", 2, $1, $3); }
+| expr_nostruct ANDEQ expr_nostruct { $$ = mk_node("ExprAssignBitAnd", 2, $1, $3); }
+| expr_nostruct OREQ expr_nostruct { $$ = mk_node("ExprAssignBitOr", 2, $1, $3); }
+| expr_nostruct PLUSEQ expr_nostruct { $$ = mk_node("ExprAssignAdd", 2, $1, $3); }
+| expr_nostruct STAREQ expr_nostruct { $$ = mk_node("ExprAssignMul", 2, $1, $3); }
+| expr_nostruct SLASHEQ expr_nostruct { $$ = mk_node("ExprAssignDiv", 2, $1, $3); }
+| expr_nostruct CARETEQ expr_nostruct { $$ = mk_node("ExprAssignBitXor", 2, $1, $3); }
+| expr_nostruct PERCENTEQ expr_nostruct { $$ = mk_node("ExprAssignRem", 2, $1, $3); }
+| expr_nostruct OROR expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiOr"), $1, $3); }
+| expr_nostruct ANDAND expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiAnd"), $1, $3); }
+| expr_nostruct EQEQ expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiEq"), $1, $3); }
+| expr_nostruct NE expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiNe"), $1, $3); }
+| expr_nostruct '<' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiLt"), $1, $3); }
+| expr_nostruct '>' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiGt"), $1, $3); }
+| expr_nostruct LE expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiLe"), $1, $3); }
+| expr_nostruct GE expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiGe"), $1, $3); }
+| expr_nostruct '|' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitOr"), $1, $3); }
+| expr_nostruct '^' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitXor"), $1, $3); }
+| expr_nostruct '&' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitAnd"), $1, $3); }
+| expr_nostruct SHL expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiShl"), $1, $3); }
+| expr_nostruct SHR expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiShr"), $1, $3); }
+| expr_nostruct '+' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiAdd"), $1, $3); }
+| expr_nostruct '-' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiSub"), $1, $3); }
+| expr_nostruct '*' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiMul"), $1, $3); }
+| expr_nostruct '/' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiDiv"), $1, $3); }
+| expr_nostruct '%' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiRem"), $1, $3); }
+| expr_nostruct DOTDOT %prec RANGE { $$ = mk_node("ExprRange", 2, $1, mk_none()); }
+| expr_nostruct DOTDOT expr_nostruct { $$ = mk_node("ExprRange", 2, $1, $3); }
+| DOTDOT expr_nostruct { $$ = mk_node("ExprRange", 2, mk_none(), $2); }
+| DOTDOT { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); }
+| expr_nostruct AS ty { $$ = mk_node("ExprCast", 2, $1, $3); }
+| expr_nostruct ':' ty { $$ = mk_node("ExprTypeAscr", 2, $1, $3); }
+| BOX expr { $$ = mk_node("ExprBox", 1, $2); }
+| expr_qualified_path
+| block_expr
+| block
+| nonblock_prefix_expr_nostruct
+;
+
+nonblock_prefix_expr_nostruct
+: '-' expr_nostruct { $$ = mk_node("ExprUnary", 2, mk_atom("UnNeg"), $2); }
+| '!' expr_nostruct { $$ = mk_node("ExprUnary", 2, mk_atom("UnNot"), $2); }
+| '*' expr_nostruct { $$ = mk_node("ExprUnary", 2, mk_atom("UnDeref"), $2); }
+| '&' maybe_mut expr_nostruct { $$ = mk_node("ExprAddrOf", 2, $2, $3); }
+| ANDAND maybe_mut expr_nostruct { $$ = mk_node("ExprAddrOf", 1, mk_node("ExprAddrOf", 2, $2, $3)); }
+| lambda_expr_nostruct
+| MOVE lambda_expr_nostruct { $$ = $2; }
+;
+
+nonblock_prefix_expr
+: '-' expr { $$ = mk_node("ExprUnary", 2, mk_atom("UnNeg"), $2); }
+| '!' expr { $$ = mk_node("ExprUnary", 2, mk_atom("UnNot"), $2); }
+| '*' expr { $$ = mk_node("ExprUnary", 2, mk_atom("UnDeref"), $2); }
+| '&' maybe_mut expr { $$ = mk_node("ExprAddrOf", 2, $2, $3); }
+| ANDAND maybe_mut expr { $$ = mk_node("ExprAddrOf", 1, mk_node("ExprAddrOf", 2, $2, $3)); }
+| lambda_expr
+| MOVE lambda_expr { $$ = $2; }
+;
+
+expr_qualified_path
+: '<' ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_qpath_params
+{
+ $$ = mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7);
+}
+| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident
+{
+ $$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 3, $2, $3, $6), $7, $10);
+}
+| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident generic_args maybe_as_trait_ref '>' MOD_SEP ident
+{
+ $$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7), $8, $11);
+}
+| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident generic_args
+{
+ $$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 3, $2, $3, $6), $7, $10, $11);
+}
+| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident generic_args maybe_as_trait_ref '>' MOD_SEP ident generic_args
+{
+ $$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7), $8, $11, $12);
+}
+
+maybe_qpath_params
+: MOD_SEP generic_args { $$ = $2; }
+| %empty { $$ = mk_none(); }
+;
+
+maybe_as_trait_ref
+: AS trait_ref { $$ = $2; }
+| %empty { $$ = mk_none(); }
+;
+
+lambda_expr
+: %prec LAMBDA
+ OROR ret_ty expr { $$ = mk_node("ExprFnBlock", 3, mk_none(), $2, $3); }
+| %prec LAMBDA
+ '|' '|' ret_ty expr { $$ = mk_node("ExprFnBlock", 3, mk_none(), $3, $4); }
+| %prec LAMBDA
+ '|' inferrable_params '|' ret_ty expr { $$ = mk_node("ExprFnBlock", 3, $2, $4, $5); }
+| %prec LAMBDA
+ '|' inferrable_params OROR lambda_expr_no_first_bar { $$ = mk_node("ExprFnBlock", 3, $2, mk_none(), $4); }
+;
+
+lambda_expr_no_first_bar
+: %prec LAMBDA
+ '|' ret_ty expr { $$ = mk_node("ExprFnBlock", 3, mk_none(), $2, $3); }
+| %prec LAMBDA
+ inferrable_params '|' ret_ty expr { $$ = mk_node("ExprFnBlock", 3, $1, $3, $4); }
+| %prec LAMBDA
+ inferrable_params OROR lambda_expr_no_first_bar { $$ = mk_node("ExprFnBlock", 3, $1, mk_none(), $3); }
+;
+
+lambda_expr_nostruct
+: %prec LAMBDA
+ OROR expr_nostruct { $$ = mk_node("ExprFnBlock", 2, mk_none(), $2); }
+| %prec LAMBDA
+ '|' '|' ret_ty expr_nostruct { $$ = mk_node("ExprFnBlock", 3, mk_none(), $3, $4); }
+| %prec LAMBDA
+ '|' inferrable_params '|' expr_nostruct { $$ = mk_node("ExprFnBlock", 2, $2, $4); }
+| %prec LAMBDA
+ '|' inferrable_params OROR lambda_expr_nostruct_no_first_bar { $$ = mk_node("ExprFnBlock", 3, $2, mk_none(), $4); }
+;
+
+lambda_expr_nostruct_no_first_bar
+: %prec LAMBDA
+ '|' ret_ty expr_nostruct { $$ = mk_node("ExprFnBlock", 3, mk_none(), $2, $3); }
+| %prec LAMBDA
+ inferrable_params '|' ret_ty expr_nostruct { $$ = mk_node("ExprFnBlock", 3, $1, $3, $4); }
+| %prec LAMBDA
+ inferrable_params OROR lambda_expr_nostruct_no_first_bar { $$ = mk_node("ExprFnBlock", 3, $1, mk_none(), $3); }
+;
+
+vec_expr
+: maybe_exprs
+| exprs ';' expr { $$ = mk_node("VecRepeat", 2, $1, $3); }
+;
+
+struct_expr_fields
+: field_inits
+| field_inits ','
+| maybe_field_inits default_field_init { $$ = ext_node($1, 1, $2); }
+| %empty { $$ = mk_none(); }
+;
+
+maybe_field_inits
+: field_inits
+| field_inits ','
+| %empty { $$ = mk_none(); }
+;
+
+field_inits
+: field_init { $$ = mk_node("FieldInits", 1, $1); }
+| field_inits ',' field_init { $$ = ext_node($1, 1, $3); }
+;
+
+field_init
+: ident { $$ = mk_node("FieldInit", 1, $1); }
+| ident ':' expr { $$ = mk_node("FieldInit", 2, $1, $3); }
+| LIT_INTEGER ':' expr { $$ = mk_node("FieldInit", 2, mk_atom(yytext), $3); }
+;
+
+default_field_init
+: DOTDOT expr { $$ = mk_node("DefaultFieldInit", 1, $2); }
+;
+
+block_expr
+: expr_match
+| expr_if
+| expr_if_let
+| expr_while
+| expr_while_let
+| expr_loop
+| expr_for
+| UNSAFE block { $$ = mk_node("UnsafeBlock", 1, $2); }
+| path_expr '!' maybe_ident braces_delimited_token_trees { $$ = mk_node("Macro", 3, $1, $3, $4); }
+;
+
+full_block_expr
+: block_expr
+| block_expr_dot
+;
+
+block_expr_dot
+: block_expr '.' path_generic_args_with_colons %prec IDENT { $$ = mk_node("ExprField", 2, $1, $3); }
+| block_expr_dot '.' path_generic_args_with_colons %prec IDENT { $$ = mk_node("ExprField", 2, $1, $3); }
+| block_expr '.' path_generic_args_with_colons '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 3, $1, $3, $5); }
+| block_expr_dot '.' path_generic_args_with_colons '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 3, $1, $3, $5); }
+| block_expr '.' path_generic_args_with_colons '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 3, $1, $3, $5); }
+| block_expr_dot '.' path_generic_args_with_colons '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 3, $1, $3, $5); }
+| block_expr '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); }
+| block_expr_dot '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); }
+;
+
+expr_match
+: MATCH expr_nostruct '{' '}' { $$ = mk_node("ExprMatch", 1, $2); }
+| MATCH expr_nostruct '{' match_clauses '}' { $$ = mk_node("ExprMatch", 2, $2, $4); }
+| MATCH expr_nostruct '{' match_clauses nonblock_match_clause '}' { $$ = mk_node("ExprMatch", 2, $2, ext_node($4, 1, $5)); }
+| MATCH expr_nostruct '{' nonblock_match_clause '}' { $$ = mk_node("ExprMatch", 2, $2, mk_node("Arms", 1, $4)); }
+;
+
+match_clauses
+: match_clause { $$ = mk_node("Arms", 1, $1); }
+| match_clauses match_clause { $$ = ext_node($1, 1, $2); }
+;
+
+match_clause
+: nonblock_match_clause ','
+| block_match_clause
+| block_match_clause ','
+;
+
+nonblock_match_clause
+: maybe_outer_attrs pats_or maybe_guard FAT_ARROW nonblock_expr { $$ = mk_node("ArmNonblock", 4, $1, $2, $3, $5); }
+| maybe_outer_attrs pats_or maybe_guard FAT_ARROW block_expr_dot { $$ = mk_node("ArmNonblock", 4, $1, $2, $3, $5); }
+;
+
+block_match_clause
+: maybe_outer_attrs pats_or maybe_guard FAT_ARROW block { $$ = mk_node("ArmBlock", 4, $1, $2, $3, $5); }
+| maybe_outer_attrs pats_or maybe_guard FAT_ARROW block_expr { $$ = mk_node("ArmBlock", 4, $1, $2, $3, $5); }
+;
+
+maybe_guard
+: IF expr_nostruct { $$ = $2; }
+| %empty { $$ = mk_none(); }
+;
+
+expr_if
+: IF expr_nostruct block { $$ = mk_node("ExprIf", 2, $2, $3); }
+| IF expr_nostruct block ELSE block_or_if { $$ = mk_node("ExprIf", 3, $2, $3, $5); }
+;
+
+expr_if_let
+: IF LET pat '=' expr_nostruct block { $$ = mk_node("ExprIfLet", 3, $3, $5, $6); }
+| IF LET pat '=' expr_nostruct block ELSE block_or_if { $$ = mk_node("ExprIfLet", 4, $3, $5, $6, $8); }
+;
+
+block_or_if
+: block
+| expr_if
+| expr_if_let
+;
+
+expr_while
+: maybe_label WHILE expr_nostruct block { $$ = mk_node("ExprWhile", 3, $1, $3, $4); }
+;
+
+expr_while_let
+: maybe_label WHILE LET pat '=' expr_nostruct block { $$ = mk_node("ExprWhileLet", 4, $1, $4, $6, $7); }
+;
+
+expr_loop
+: maybe_label LOOP block { $$ = mk_node("ExprLoop", 2, $1, $3); }
+;
+
+expr_for
+: maybe_label FOR pat IN expr_nostruct block { $$ = mk_node("ExprForLoop", 4, $1, $3, $5, $6); }
+;
+
+maybe_label
+: lifetime ':'
+| %empty { $$ = mk_none(); }
+;
+
+let
+: LET pat maybe_ty_ascription maybe_init_expr ';' { $$ = mk_node("DeclLocal", 3, $2, $3, $4); }
+;
+
+////////////////////////////////////////////////////////////////////////
+// Part 5: Macros and misc. rules
+////////////////////////////////////////////////////////////////////////
+
+lit
+: LIT_BYTE { $$ = mk_node("LitByte", 1, mk_atom(yytext)); }
+| LIT_CHAR { $$ = mk_node("LitChar", 1, mk_atom(yytext)); }
+| LIT_INTEGER { $$ = mk_node("LitInteger", 1, mk_atom(yytext)); }
+| LIT_FLOAT { $$ = mk_node("LitFloat", 1, mk_atom(yytext)); }
+| TRUE { $$ = mk_node("LitBool", 1, mk_atom(yytext)); }
+| FALSE { $$ = mk_node("LitBool", 1, mk_atom(yytext)); }
+| str
+;
+
+str
+: LIT_STR { $$ = mk_node("LitStr", 1, mk_atom(yytext), mk_atom("CookedStr")); }
+| LIT_STR_RAW { $$ = mk_node("LitStr", 1, mk_atom(yytext), mk_atom("RawStr")); }
+| LIT_BYTE_STR { $$ = mk_node("LitByteStr", 1, mk_atom(yytext), mk_atom("ByteStr")); }
+| LIT_BYTE_STR_RAW { $$ = mk_node("LitByteStr", 1, mk_atom(yytext), mk_atom("RawByteStr")); }
+;
+
+maybe_ident
+: %empty { $$ = mk_none(); }
+| ident
+;
+
+ident
+: IDENT { $$ = mk_node("ident", 1, mk_atom(yytext)); }
+// Weak keywords that can be used as identifiers
+| CATCH { $$ = mk_node("ident", 1, mk_atom(yytext)); }
+| DEFAULT { $$ = mk_node("ident", 1, mk_atom(yytext)); }
+| UNION { $$ = mk_node("ident", 1, mk_atom(yytext)); }
+;
+
+unpaired_token
+: SHL { $$ = mk_atom(yytext); }
+| SHR { $$ = mk_atom(yytext); }
+| LE { $$ = mk_atom(yytext); }
+| EQEQ { $$ = mk_atom(yytext); }
+| NE { $$ = mk_atom(yytext); }
+| GE { $$ = mk_atom(yytext); }
+| ANDAND { $$ = mk_atom(yytext); }
+| OROR { $$ = mk_atom(yytext); }
+| LARROW { $$ = mk_atom(yytext); }
+| SHLEQ { $$ = mk_atom(yytext); }
+| SHREQ { $$ = mk_atom(yytext); }
+| MINUSEQ { $$ = mk_atom(yytext); }
+| ANDEQ { $$ = mk_atom(yytext); }
+| OREQ { $$ = mk_atom(yytext); }
+| PLUSEQ { $$ = mk_atom(yytext); }
+| STAREQ { $$ = mk_atom(yytext); }
+| SLASHEQ { $$ = mk_atom(yytext); }
+| CARETEQ { $$ = mk_atom(yytext); }
+| PERCENTEQ { $$ = mk_atom(yytext); }
+| DOTDOT { $$ = mk_atom(yytext); }
+| DOTDOTDOT { $$ = mk_atom(yytext); }
+| MOD_SEP { $$ = mk_atom(yytext); }
+| RARROW { $$ = mk_atom(yytext); }
+| FAT_ARROW { $$ = mk_atom(yytext); }
+| LIT_BYTE { $$ = mk_atom(yytext); }
+| LIT_CHAR { $$ = mk_atom(yytext); }
+| LIT_INTEGER { $$ = mk_atom(yytext); }
+| LIT_FLOAT { $$ = mk_atom(yytext); }
+| LIT_STR { $$ = mk_atom(yytext); }
+| LIT_STR_RAW { $$ = mk_atom(yytext); }
+| LIT_BYTE_STR { $$ = mk_atom(yytext); }
+| LIT_BYTE_STR_RAW { $$ = mk_atom(yytext); }
+| IDENT { $$ = mk_atom(yytext); }
+| UNDERSCORE { $$ = mk_atom(yytext); }
+| LIFETIME { $$ = mk_atom(yytext); }
+| SELF { $$ = mk_atom(yytext); }
+| STATIC { $$ = mk_atom(yytext); }
+| ABSTRACT { $$ = mk_atom(yytext); }
+| ALIGNOF { $$ = mk_atom(yytext); }
+| AS { $$ = mk_atom(yytext); }
+| BECOME { $$ = mk_atom(yytext); }
+| BREAK { $$ = mk_atom(yytext); }
+| CATCH { $$ = mk_atom(yytext); }
+| CRATE { $$ = mk_atom(yytext); }
+| DEFAULT { $$ = mk_atom(yytext); }
+| DO { $$ = mk_atom(yytext); }
+| ELSE { $$ = mk_atom(yytext); }
+| ENUM { $$ = mk_atom(yytext); }
+| EXTERN { $$ = mk_atom(yytext); }
+| FALSE { $$ = mk_atom(yytext); }
+| FINAL { $$ = mk_atom(yytext); }
+| FN { $$ = mk_atom(yytext); }
+| FOR { $$ = mk_atom(yytext); }
+| IF { $$ = mk_atom(yytext); }
+| IMPL { $$ = mk_atom(yytext); }
+| IN { $$ = mk_atom(yytext); }
+| LET { $$ = mk_atom(yytext); }
+| LOOP { $$ = mk_atom(yytext); }
+| MACRO { $$ = mk_atom(yytext); }
+| MATCH { $$ = mk_atom(yytext); }
+| MOD { $$ = mk_atom(yytext); }
+| MOVE { $$ = mk_atom(yytext); }
+| MUT { $$ = mk_atom(yytext); }
+| OFFSETOF { $$ = mk_atom(yytext); }
+| OVERRIDE { $$ = mk_atom(yytext); }
+| PRIV { $$ = mk_atom(yytext); }
+| PUB { $$ = mk_atom(yytext); }
+| PURE { $$ = mk_atom(yytext); }
+| REF { $$ = mk_atom(yytext); }
+| RETURN { $$ = mk_atom(yytext); }
+| STRUCT { $$ = mk_atom(yytext); }
+| SIZEOF { $$ = mk_atom(yytext); }
+| SUPER { $$ = mk_atom(yytext); }
+| TRUE { $$ = mk_atom(yytext); }
+| TRAIT { $$ = mk_atom(yytext); }
+| TYPE { $$ = mk_atom(yytext); }
+| UNION { $$ = mk_atom(yytext); }
+| UNSAFE { $$ = mk_atom(yytext); }
+| UNSIZED { $$ = mk_atom(yytext); }
+| USE { $$ = mk_atom(yytext); }
+| VIRTUAL { $$ = mk_atom(yytext); }
+| WHILE { $$ = mk_atom(yytext); }
+| YIELD { $$ = mk_atom(yytext); }
+| CONTINUE { $$ = mk_atom(yytext); }
+| PROC { $$ = mk_atom(yytext); }
+| BOX { $$ = mk_atom(yytext); }
+| CONST { $$ = mk_atom(yytext); }
+| WHERE { $$ = mk_atom(yytext); }
+| TYPEOF { $$ = mk_atom(yytext); }
+| INNER_DOC_COMMENT { $$ = mk_atom(yytext); }
+| OUTER_DOC_COMMENT { $$ = mk_atom(yytext); }
+| SHEBANG { $$ = mk_atom(yytext); }
+| STATIC_LIFETIME { $$ = mk_atom(yytext); }
+| ';' { $$ = mk_atom(yytext); }
+| ',' { $$ = mk_atom(yytext); }
+| '.' { $$ = mk_atom(yytext); }
+| '@' { $$ = mk_atom(yytext); }
+| '#' { $$ = mk_atom(yytext); }
+| '~' { $$ = mk_atom(yytext); }
+| ':' { $$ = mk_atom(yytext); }
+| '$' { $$ = mk_atom(yytext); }
+| '=' { $$ = mk_atom(yytext); }
+| '?' { $$ = mk_atom(yytext); }
+| '!' { $$ = mk_atom(yytext); }
+| '<' { $$ = mk_atom(yytext); }
+| '>' { $$ = mk_atom(yytext); }
+| '-' { $$ = mk_atom(yytext); }
+| '&' { $$ = mk_atom(yytext); }
+| '|' { $$ = mk_atom(yytext); }
+| '+' { $$ = mk_atom(yytext); }
+| '*' { $$ = mk_atom(yytext); }
+| '/' { $$ = mk_atom(yytext); }
+| '^' { $$ = mk_atom(yytext); }
+| '%' { $$ = mk_atom(yytext); }
+;
+
+token_trees
+: %empty { $$ = mk_node("TokenTrees", 0); }
+| token_trees token_tree { $$ = ext_node($1, 1, $2); }
+;
+
+token_tree
+: delimited_token_trees
+| unpaired_token { $$ = mk_node("TTTok", 1, $1); }
+;
+
+delimited_token_trees
+: parens_delimited_token_trees
+| braces_delimited_token_trees
+| brackets_delimited_token_trees
+;
+
+parens_delimited_token_trees
+: '(' token_trees ')'
+{
+ $$ = mk_node("TTDelim", 3,
+ mk_node("TTTok", 1, mk_atom("(")),
+ $2,
+ mk_node("TTTok", 1, mk_atom(")")));
+}
+;
+
+braces_delimited_token_trees
+: '{' token_trees '}'
+{
+ $$ = mk_node("TTDelim", 3,
+ mk_node("TTTok", 1, mk_atom("{")),
+ $2,
+ mk_node("TTTok", 1, mk_atom("}")));
+}
+;
+
+brackets_delimited_token_trees
+: '[' token_trees ']'
+{
+ $$ = mk_node("TTDelim", 3,
+ mk_node("TTTok", 1, mk_atom("[")),
+ $2,
+ mk_node("TTTok", 1, mk_atom("]")));
+}
+;
diff --git a/src/grammar/raw-string-literal-ambiguity.md b/src/grammar/raw-string-literal-ambiguity.md
new file mode 100644
index 0000000000000..c909f2333148a
--- /dev/null
+++ b/src/grammar/raw-string-literal-ambiguity.md
@@ -0,0 +1,64 @@
+Rust's lexical grammar is not context-free. Raw string literals are the source
+of the problem. Informally, a raw string literal is an `r`, followed by `N`
+hashes (where N can be zero), a quote, any characters, then a quote followed
+by `N` hashes. Critically, once inside the first pair of quotes,
+another quote cannot be followed by `N` consecutive hashes. e.g.
+`r###""###"###` is invalid.
+
+This grammar describes this as best possible:
+
+ R -> 'r' S
+ S -> '"' B '"'
+ S -> '#' S '#'
+ B -> . B
+ B -> ε
+
+Where `.` represents any character, and `ε` the empty string. Consider the
+string `r#""#"#`. This string is not a valid raw string literal, but can be
+accepted as one by the above grammar, using the derivation:
+
+ R : #""#"#
+ S : ""#"
+ S : "#
+ B : #
+ B : ε
+
+(Where `T : U` means the rule `T` is applied, and `U` is the remainder of the
+string.) The difficulty arises from the fact that it is fundamentally
+context-sensitive. In particular, the context needed is the number of hashes.
+
+To prove that Rust's string literals are not context-free, we will use
+the fact that context-free languages are closed under intersection with
+regular languages, and the
+[pumping lemma for context-free languages](https://en.wikipedia.org/wiki/Pumping_lemma_for_context-free_languages).
+
+Consider the regular language `R = r#+""#*"#+`. If Rust's raw string literals are
+context-free, then their intersection with `R`, `R'`, should also be context-free.
+Therefore, to prove that raw string literals are not context-free,
+it is sufficient to prove that `R'` is not context-free.
+
+The language `R'` is `{r#^n""#^m"#^n | m < n}`.
+
+Assume `R'` *is* context-free. Then `R'` has some pumping length `p > 0` for which
+the pumping lemma applies. Consider the following string `s` in `R'`:
+
+`r#^p""#^{p-1}"#^p`
+
+e.g. for `p = 2`: `s = r##""#"##`
+
+Then `s = uvwxy` for some choice of `uvwxy` such that `vx` is non-empty,
+`|vwx| < p+1`, and `uv^iwx^iy` is in `R'` for all `i >= 0`.
+
+Neither `v` nor `x` can contain a `"` or `r`, as the number of these characters
+in any string in `R'` is fixed. So `v` and `x` contain only hashes.
+Consequently, of the three sequences of hashes, `v` and `x` combined
+can only pump two of them.
+If we ever choose the central sequence of hashes, then one of the outer sequences
+will not grow when we pump, leading to an imbalance between the outer sequences.
+Therefore, we must pump both outer sequences of hashes. However,
+there are `p+2` characters between these two sequences of hashes, and `|vwx|` must
+be less than `p+1`. Therefore we have a contradiction, and `R'` must not be
+context-free.
+
+Since `R'` is not context-free, it follows that the Rust's raw string literals
+must not be context-free.
diff --git a/src/grammar/testparser.py b/src/grammar/testparser.py
new file mode 100755
index 0000000000000..4b5a7fb9e10b5
--- /dev/null
+++ b/src/grammar/testparser.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+
+# ignore-tidy-linelength
+
+import sys
+
+import os
+import subprocess
+import argparse
+
+# usage: testparser.py [-h] [-p PARSER [PARSER ...]] -s SOURCE_DIR
+
+# Parsers should read from stdin and return exit status 0 for a
+# successful parse, and nonzero for an unsuccessful parse
+
+parser = argparse.ArgumentParser()
+parser.add_argument('-p', '--parser', nargs='+')
+parser.add_argument('-s', '--source-dir', nargs=1, required=True)
+args = parser.parse_args(sys.argv[1:])
+
+total = 0
+ok = {}
+bad = {}
+for parser in args.parser:
+ ok[parser] = 0
+ bad[parser] = []
+devnull = open(os.devnull, 'w')
+print("\n")
+
+for base, dirs, files in os.walk(args.source_dir[0]):
+ for f in filter(lambda p: p.endswith('.rs'), files):
+ p = os.path.join(base, f)
+ parse_fail = 'parse-fail' in p
+ if sys.version_info.major == 3:
+ lines = open(p, encoding='utf-8').readlines()
+ else:
+ lines = open(p).readlines()
+ if any('ignore-test' in line or 'ignore-lexer-test' in line for line in lines):
+ continue
+ total += 1
+ for parser in args.parser:
+ if subprocess.call(parser, stdin=open(p), stderr=subprocess.STDOUT, stdout=devnull) == 0:
+ if parse_fail:
+ bad[parser].append(p)
+ else:
+ ok[parser] += 1
+ else:
+ if parse_fail:
+ ok[parser] += 1
+ else:
+ bad[parser].append(p)
+ parser_stats = ', '.join(['{}: {}'.format(parser, ok[parser]) for parser in args.parser])
+ sys.stdout.write("\033[K\r total: {}, {}, scanned {}"
+ .format(total, os.path.relpath(parser_stats), os.path.relpath(p)))
+
+devnull.close()
+
+print("\n")
+
+for parser in args.parser:
+ filename = os.path.basename(parser) + '.bad'
+ print("writing {} files that did not yield the correct result with {} to {}".format(len(bad[parser]), parser, filename))
+ with open(filename, "w") as f:
+ for p in bad[parser]:
+ f.write(p)
+ f.write("\n")
diff --git a/src/grammar/tokens.h b/src/grammar/tokens.h
new file mode 100644
index 0000000000000..297e3dc841e87
--- /dev/null
+++ b/src/grammar/tokens.h
@@ -0,0 +1,99 @@
+enum Token {
+ SHL = 257, // Parser generators reserve 0-256 for char literals
+ SHR,
+ LE,
+ EQEQ,
+ NE,
+ GE,
+ ANDAND,
+ OROR,
+ SHLEQ,
+ SHREQ,
+ MINUSEQ,
+ ANDEQ,
+ OREQ,
+ PLUSEQ,
+ STAREQ,
+ SLASHEQ,
+ CARETEQ,
+ PERCENTEQ,
+ DOTDOT,
+ DOTDOTDOT,
+ MOD_SEP,
+ LARROW,
+ RARROW,
+ FAT_ARROW,
+ LIT_BYTE,
+ LIT_CHAR,
+ LIT_INTEGER,
+ LIT_FLOAT,
+ LIT_STR,
+ LIT_STR_RAW,
+ LIT_BYTE_STR,
+ LIT_BYTE_STR_RAW,
+ IDENT,
+ UNDERSCORE,
+ LIFETIME,
+
+ // keywords
+ SELF,
+ STATIC,
+ ABSTRACT,
+ ALIGNOF,
+ AS,
+ BECOME,
+ BREAK,
+ CATCH,
+ CRATE,
+ DEFAULT,
+ DO,
+ ELSE,
+ ENUM,
+ EXTERN,
+ FALSE,
+ FINAL,
+ FN,
+ FOR,
+ IF,
+ IMPL,
+ IN,
+ LET,
+ LOOP,
+ MACRO,
+ MATCH,
+ MOD,
+ MOVE,
+ MUT,
+ OFFSETOF,
+ OVERRIDE,
+ PRIV,
+ PUB,
+ PURE,
+ REF,
+ RETURN,
+ SIZEOF,
+ STRUCT,
+ SUPER,
+ UNION,
+ TRUE,
+ TRAIT,
+ TYPE,
+ UNSAFE,
+ UNSIZED,
+ USE,
+ VIRTUAL,
+ WHILE,
+ YIELD,
+ CONTINUE,
+ PROC,
+ BOX,
+ CONST,
+ WHERE,
+ TYPEOF,
+ INNER_DOC_COMMENT,
+ OUTER_DOC_COMMENT,
+
+ SHEBANG,
+ SHEBANG_LINE,
+ STATIC_LIFETIME
+};
diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs
index d2bdda83fa998..a9c5bce4c25fc 100644
--- a/src/liballoc/borrow.rs
+++ b/src/liballoc/borrow.rs
@@ -207,47 +207,6 @@ impl Clone for Cow<'_, B> {
}
impl Cow<'_, B> {
- /// Returns true if the data is borrowed, i.e. if `to_mut` would require additional work.
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(cow_is_borrowed)]
- /// use std::borrow::Cow;
- ///
- /// let cow = Cow::Borrowed("moo");
- /// assert!(cow.is_borrowed());
- ///
- /// let bull: Cow<'_, str> = Cow::Owned("...moo?".to_string());
- /// assert!(!bull.is_borrowed());
- /// ```
- #[unstable(feature = "cow_is_borrowed", issue = "65143")]
- pub fn is_borrowed(&self) -> bool {
- match *self {
- Borrowed(_) => true,
- Owned(_) => false,
- }
- }
-
- /// Returns true if the data is owned, i.e. if `to_mut` would be a no-op.
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(cow_is_borrowed)]
- /// use std::borrow::Cow;
- ///
- /// let cow: Cow<'_, str> = Cow::Owned("moo".to_string());
- /// assert!(cow.is_owned());
- ///
- /// let bull = Cow::Borrowed("...moo?");
- /// assert!(!bull.is_owned());
- /// ```
- #[unstable(feature = "cow_is_borrowed", issue = "65143")]
- pub fn is_owned(&self) -> bool {
- !self.is_borrowed()
- }
-
/// Acquires a mutable reference to the owned form of the data.
///
/// Clones the data if it is not already owned.
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 567b8ea722491..c61e3183409f2 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -29,8 +29,10 @@
//! Nil,
//! }
//!
-//! let list: List = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil))));
-//! println!("{:?}", list);
+//! fn main() {
+//! let list: List = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil))));
+//! println!("{:?}", list);
+//! }
//! ```
//!
//! This will print `Cons(1, Cons(2, Nil))`.
@@ -142,9 +144,6 @@ impl Box {
#[unstable(feature = "new_uninit", issue = "63291")]
pub fn new_uninit() -> Box> {
let layout = alloc::Layout::new::>();
- if layout.size() == 0 {
- return Box(NonNull::dangling().into())
- }
let ptr = unsafe {
Global.alloc(layout)
.unwrap_or_else(|_| alloc::handle_alloc_error(layout))
@@ -185,16 +184,9 @@ impl Box<[T]> {
#[unstable(feature = "new_uninit", issue = "63291")]
pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit]> {
let layout = alloc::Layout::array::>(len).unwrap();
- let ptr = if layout.size() == 0 {
- NonNull::dangling()
- } else {
- unsafe {
- Global.alloc(layout)
- .unwrap_or_else(|_| alloc::handle_alloc_error(layout))
- .cast()
- }
- };
- let slice = unsafe { slice::from_raw_parts_mut(ptr.as_ptr(), len) };
+ let ptr = unsafe { alloc::alloc(layout) };
+ let unique = Unique::new(ptr).unwrap_or_else(|| alloc::handle_alloc_error(layout));
+ let slice = unsafe { slice::from_raw_parts_mut(unique.cast().as_ptr(), len) };
Box(Unique::from(slice))
}
}
@@ -383,12 +375,14 @@ impl Box {
/// ```
/// #![feature(box_into_raw_non_null)]
///
- /// let x = Box::new(5);
- /// let ptr = Box::into_raw_non_null(x);
+ /// fn main() {
+ /// let x = Box::new(5);
+ /// let ptr = Box::into_raw_non_null(x);
///
- /// // Clean up the memory by converting the NonNull pointer back
- /// // into a Box and letting the Box be dropped.
- /// let x = unsafe { Box::from_raw(ptr.as_ptr()) };
+ /// // Clean up the memory by converting the NonNull pointer back
+ /// // into a Box and letting the Box be dropped.
+ /// let x = unsafe { Box::from_raw(ptr.as_ptr()) };
+ /// }
/// ```
#[unstable(feature = "box_into_raw_non_null", issue = "47336")]
#[inline]
@@ -434,19 +428,23 @@ impl Box {
/// Simple usage:
///
/// ```
- /// let x = Box::new(41);
- /// let static_ref: &'static mut usize = Box::leak(x);
- /// *static_ref += 1;
- /// assert_eq!(*static_ref, 42);
+ /// fn main() {
+ /// let x = Box::new(41);
+ /// let static_ref: &'static mut usize = Box::leak(x);
+ /// *static_ref += 1;
+ /// assert_eq!(*static_ref, 42);
+ /// }
/// ```
///
/// Unsized data:
///
/// ```
- /// let x = vec![1, 2, 3].into_boxed_slice();
- /// let static_ref = Box::leak(x);
- /// static_ref[0] = 4;
- /// assert_eq!(*static_ref, [4, 2, 3]);
+ /// fn main() {
+ /// let x = vec![1, 2, 3].into_boxed_slice();
+ /// let static_ref = Box::leak(x);
+ /// static_ref[0] = 4;
+ /// assert_eq!(*static_ref, [4, 2, 3]);
+ /// }
/// ```
#[stable(feature = "box_leak", since = "1.26.0")]
#[inline]
@@ -782,9 +780,11 @@ impl Box {
/// }
/// }
///
- /// let my_string = "Hello World".to_string();
- /// print_if_string(Box::new(my_string));
- /// print_if_string(Box::new(0i8));
+ /// fn main() {
+ /// let my_string = "Hello World".to_string();
+ /// print_if_string(Box::new(my_string));
+ /// print_if_string(Box::new(0i8));
+ /// }
/// ```
pub fn downcast(self) -> Result, Box> {
if self.is::() {
@@ -814,9 +814,11 @@ impl Box {
/// }
/// }
///
- /// let my_string = "Hello World".to_string();
- /// print_if_string(Box::new(my_string));
- /// print_if_string(Box::new(0i8));
+ /// fn main() {
+ /// let my_string = "Hello World".to_string();
+ /// print_if_string(Box::new(my_string));
+ /// print_if_string(Box::new(0i8));
+ /// }
/// ```
pub fn downcast(self) -> Result, Box> {
>::downcast(self).map_err(|s| unsafe {
@@ -881,33 +883,11 @@ impl Iterator for Box {
fn nth(&mut self, n: usize) -> Option {
(**self).nth(n)
}
- fn last(self) -> Option {
- BoxIter::last(self)
- }
-}
-
-trait BoxIter {
- type Item;
- fn last(self) -> Option;
-}
-
-impl BoxIter for Box {
- type Item = I::Item;
- default fn last(self) -> Option {
- #[inline]
- fn some(_: Option, x: T) -> Option {
- Some(x)
- }
-
- self.fold(None, some)
- }
}
-/// Specialization for sized `I`s that uses `I`s implementation of `last()`
-/// instead of the default.
#[stable(feature = "rust1", since = "1.0.0")]
-impl BoxIter for Box {
- fn last(self) -> Option {
+impl Iterator for Box {
+ fn last(self) -> Option where I: Sized {
(*self).last()
}
}
diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs
index 83fd4485f7321..ddf012d15029a 100644
--- a/src/liballoc/collections/btree/map.rs
+++ b/src/liballoc/collections/btree/map.rs
@@ -2226,12 +2226,14 @@ impl<'a, K: Ord, V: Default> Entry<'a, K, V> {
/// # Examples
///
/// ```
+ /// # fn main() {
/// use std::collections::BTreeMap;
///
/// let mut map: BTreeMap<&str, Option> = BTreeMap::new();
/// map.entry("poneyland").or_default();
///
/// assert_eq!(map["poneyland"], None);
+ /// # }
/// ```
pub fn or_default(self) -> &'a mut V {
match self {
diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs
index f0796354e00c3..0cb91ba4c81da 100644
--- a/src/liballoc/collections/btree/set.rs
+++ b/src/liballoc/collections/btree/set.rs
@@ -2,7 +2,7 @@
// to TreeMap
use core::borrow::Borrow;
-use core::cmp::Ordering::{Less, Greater, Equal};
+use core::cmp::Ordering::{self, Less, Greater, Equal};
use core::cmp::{max, min};
use core::fmt::{self, Debug};
use core::iter::{Peekable, FromIterator, FusedIterator};
@@ -109,77 +109,6 @@ pub struct Range<'a, T: 'a> {
iter: btree_map::Range<'a, T, ()>,
}
-/// Core of SymmetricDifference and Union.
-/// More efficient than btree.map.MergeIter,
-/// and crucially for SymmetricDifference, nexts() reports on both sides.
-#[derive(Clone)]
-struct MergeIterInner
- where I: Iterator,
- I::Item: Copy,
-{
- a: I,
- b: I,
- peeked: Option>,
-}
-
-#[derive(Copy, Clone, Debug)]
-enum MergeIterPeeked {
- A(I::Item),
- B(I::Item),
-}
-
-impl MergeIterInner
- where I: ExactSizeIterator + FusedIterator,
- I::Item: Copy + Ord,
-{
- fn new(a: I, b: I) -> Self {
- MergeIterInner { a, b, peeked: None }
- }
-
- fn nexts(&mut self) -> (Option, Option