diff --git a/.github/ISSUE_TEMPLATE/tracking_issue.md b/.github/ISSUE_TEMPLATE/tracking_issue.md index f93591204cd98..9457cce11afbe 100644 --- a/.github/ISSUE_TEMPLATE/tracking_issue.md +++ b/.github/ISSUE_TEMPLATE/tracking_issue.md @@ -36,11 +36,11 @@ for larger features an implementation could be broken up into multiple PRs. - [ ] Implement the RFC (cc @rust-lang/XXX -- can anyone write up mentoring instructions?) -- [ ] Adjust documentation ([see instructions on rustc-guide][doc-guide]) -- [ ] Stabilization PR ([see instructions on rustc-guide][stabilization-guide]) +- [ ] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide]) +- [ ] Stabilization PR ([see instructions on rustc-dev-guide][stabilization-guide]) -[stabilization-guide]: https://rust-lang.github.io/rustc-guide/stabilization_guide.html#stabilization-pr -[doc-guide]: https://rust-lang.github.io/rustc-guide/stabilization_guide.html#documentation-prs +[stabilization-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#stabilization-pr +[doc-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#documentation-prs ### Unresolved Questions <!-- diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a58d4f2a7c6a4..2843944b2e181 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,7 +19,7 @@ hop on the [Rust Discord server][rust-discord] or [Rust Zulip server][rust-zulip As a reminder, all contributors are expected to follow our [Code of Conduct][coc]. -The [rustc-guide] is your friend! It describes how the compiler works and how +The [rustc-dev-guide] is your friend! It describes how the compiler works and how to contribute to it in more detail than this document. If this is your first time contributing, the [walkthrough] chapter of the guide @@ -29,8 +29,8 @@ can give you a good example of how a typical contribution would go. [rust-discord]: http://discord.gg/rust-lang [rust-zulip]: https://rust-lang.zulipchat.com [coc]: https://www.rust-lang.org/conduct.html -[rustc-guide]: https://rust-lang.github.io/rustc-guide/ -[walkthrough]: https://rust-lang.github.io/rustc-guide/walkthrough.html +[rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/ +[walkthrough]: https://rustc-dev-guide.rust-lang.org/walkthrough.html ## Feature Requests [feature-requests]: #feature-requests @@ -103,12 +103,12 @@ $ RUST_BACKTRACE=1 rustc ... ## The Build System For info on how to configure and build the compiler, please see [this -chapter][rustcguidebuild] of the rustc-guide. This chapter contains info for +chapter][rustcguidebuild] of the rustc-dev-guide. This chapter contains info for contributions to the compiler and the standard library. It also lists some really useful commands to the build system (`./x.py`), which could save you a lot of time. -[rustcguidebuild]: https://rust-lang.github.io/rustc-guide/building/how-to-build-and-run.html +[rustcguidebuild]: https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html ## Pull Requests [pull-requests]: #pull-requests @@ -336,9 +336,9 @@ to check small fixes. For example, `rustdoc src/doc/reference.md` will render reference to `doc/reference.html`. The CSS might be messed up, but you can verify that the HTML is right. -Additionally, contributions to the [rustc-guide] are always welcome. Contributions +Additionally, contributions to the [rustc-dev-guide] are always welcome. Contributions can be made directly at [the -rust-lang/rustc-guide](https://github.com/rust-lang/rustc-guide) repo. The issue +rust-lang/rustc-dev-guide](https://github.com/rust-lang/rustc-dev-guide) repo. The issue tracker in that repo is also a great way to find things that need doing. There are issues for beginners and advanced compiler devs alike! @@ -434,7 +434,7 @@ For people new to Rust, and just starting to contribute, or even for more seasoned developers, some useful places to look for information are: -* The [rustc guide] contains information about how various parts of the compiler work and how to contribute to the compiler +* The [rustc dev guide] contains information about how various parts of the compiler work and how to contribute to the compiler * [Rust Forge][rustforge] contains additional documentation, including write-ups of how to achieve common tasks * The [Rust Internals forum][rif], a place to ask questions and discuss Rust's internals @@ -448,7 +448,7 @@ are: * **Google!** ([search only in Rust Documentation][gsearchdocs] to find types, traits, etc. quickly) * Don't be afraid to ask! The Rust community is friendly and helpful. -[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html +[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/about-this-guide.html [gdfrustc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ [gsearchdocs]: https://www.google.com/search?q=site:doc.rust-lang.org+your+query+here [rif]: http://internals.rust-lang.org @@ -456,5 +456,5 @@ are: [rustforge]: https://forge.rust-lang.org/ [tlgba]: http://tomlee.co/2014/04/a-more-detailed-tour-of-the-rust-compiler/ [ro]: http://www.rustaceans.org/ -[rctd]: https://rust-lang.github.io/rustc-guide/tests/intro.html +[rctd]: https://rustc-dev-guide.rust-lang.org/tests/intro.html [cheatsheet]: https://buildbot2.rust-lang.org/homu/ diff --git a/README.md b/README.md index 61d3c9e115720..1cd9b8a3a2ae1 100644 --- a/README.md +++ b/README.md @@ -15,13 +15,13 @@ Read ["Installation"] from [The Book]. ## Installing from Source _Note: If you wish to contribute to the compiler, you should read [this -chapter][rustcguidebuild] of the rustc-guide instead of this section._ +chapter][rustcguidebuild] of the rustc-dev-guide instead of this section._ The Rust build system has a Python script called `x.py` to bootstrap building the compiler. More information about it may be found by running `./x.py --help` -or reading the [rustc guide][rustcguidebuild]. +or reading the [rustc dev guide][rustcguidebuild]. -[rustcguidebuild]: https://rust-lang.github.io/rustc-guide/building/how-to-build-and-run.html +[rustcguidebuild]: https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html ### Building on *nix 1. Make sure you have installed the dependencies: @@ -249,13 +249,13 @@ Most real-time collaboration happens in a variety of channels on the community, documentation, and all major contribution areas in the Rust ecosystem. A good place to ask for help would be the #help channel. -The [rustc guide] might be a good place to start if you want to find out how +The [rustc dev 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 -[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html +[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/about-this-guide.html [rustdocs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ ## License diff --git a/src/README.md b/src/README.md index 2f7cf90c5f030..b69a92a723778 100644 --- a/src/README.md +++ b/src/README.md @@ -3,6 +3,6 @@ This directory contains the source code of the rust project, including: - `libstd` - Various submodules for tools, like rustdoc, rls, etc. -For more information on how various parts of the compiler work, see the [rustc guide]. +For more information on how various parts of the compiler work, see the [rustc dev guide]. -[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html +[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/about-this-guide.html diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs index 7cffc47293070..f0e0f92af55fc 100644 --- a/src/bootstrap/toolstate.rs +++ b/src/bootstrap/toolstate.rs @@ -215,6 +215,9 @@ impl Step for ToolStateCheck { tool, old_state, state ); } else { + // This warning only appears in the logs, which most + // people won't read. It's mostly here for testing and + // debugging. eprintln!( "warning: Tool `{}` is not test-pass (is `{}`), \ this should be fixed before beta is branched.", @@ -222,6 +225,11 @@ impl Step for ToolStateCheck { ); } } + // `publish_toolstate.py` is responsible for updating + // `latest.json` and creating comments/issues warning people + // if there is a regression. That all happens in a separate CI + // job on the master branch once the PR has passed all tests + // on the `auto` branch. } } @@ -230,7 +238,7 @@ impl Step for ToolStateCheck { } if builder.config.channel == "nightly" && env::var_os("TOOLSTATE_PUBLISH").is_some() { - commit_toolstate_change(&toolstates, in_beta_week); + commit_toolstate_change(&toolstates); } } @@ -325,11 +333,11 @@ fn prepare_toolstate_config(token: &str) { Err(_) => false, }; if !success { - panic!("git config key={} value={} successful (status: {:?})", key, value, status); + panic!("git config key={} value={} failed (status: {:?})", key, value, status); } } - // If changing anything here, then please check that src/ci/publish_toolstate.sh is up to date + // If changing anything here, then please check that `src/ci/publish_toolstate.sh` is up to date // as well. git_config("user.email", "7378925+rust-toolstate-update@users.noreply.github.com"); git_config("user.name", "Rust Toolstate Update"); @@ -373,14 +381,14 @@ fn read_old_toolstate() -> Vec<RepoState> { /// /// * See <https://help.github.com/articles/about-commit-email-addresses/> /// if a private email by GitHub is wanted. -fn commit_toolstate_change(current_toolstate: &ToolstateData, in_beta_week: bool) { - let old_toolstate = read_old_toolstate(); - +fn commit_toolstate_change(current_toolstate: &ToolstateData) { let message = format!("({} CI update)", OS.expect("linux/windows only")); let mut success = false; for _ in 1..=5 { - // Update the toolstate results (the new commit-to-toolstate mapping) in the toolstate repo. - change_toolstate(¤t_toolstate, &old_toolstate, in_beta_week); + // Upload the test results (the new commit-to-toolstate mapping) to the toolstate repo. + // This does *not* change the "current toolstate"; that only happens post-landing + // via `src/ci/docker/publish_toolstate.sh`. + publish_test_results(¤t_toolstate); // `git commit` failing means nothing to commit. let status = t!(Command::new("git") @@ -429,31 +437,12 @@ fn commit_toolstate_change(current_toolstate: &ToolstateData, in_beta_week: bool } } -fn change_toolstate( - current_toolstate: &ToolstateData, - old_toolstate: &[RepoState], - in_beta_week: bool, -) { - let mut regressed = false; - for repo_state in old_toolstate { - let tool = &repo_state.tool; - let state = repo_state.state(); - let new_state = current_toolstate[tool.as_str()]; - - if new_state != state { - eprintln!("The state of `{}` has changed from `{}` to `{}`", tool, state, new_state); - if new_state < state { - if !NIGHTLY_TOOLS.iter().any(|(name, _path)| name == tool) { - regressed = true; - } - } - } - } - - if regressed && in_beta_week { - std::process::exit(1); - } - +/// Updates the "history" files with the latest results. +/// +/// These results will later be promoted to `latest.json` by the +/// `publish_toolstate.py` script if the PR passes all tests and is merged to +/// master. +fn publish_test_results(current_toolstate: &ToolstateData) { let commit = t!(std::process::Command::new("git").arg("rev-parse").arg("HEAD").output()); let commit = t!(String::from_utf8(commit.stdout)); diff --git a/src/ci/publish_toolstate.sh b/src/ci/publish_toolstate.sh index 7c43d034d8b7f..691df04e754a6 100755 --- a/src/ci/publish_toolstate.sh +++ b/src/ci/publish_toolstate.sh @@ -23,7 +23,9 @@ GIT_COMMIT_MSG="$(git log --format=%s -n1 HEAD)" cd rust-toolstate FAILURE=1 for RETRY_COUNT in 1 2 3 4 5; do - # The purpose is to publish the new "current" toolstate in the toolstate repo. + # The purpose of this is to publish the new "current" toolstate in the toolstate repo. + # This happens post-landing, on master. + # (Publishing the per-commit test results happens pre-landing in src/bootstrap/toolstate.rs). "$(ciCheckoutPath)/src/tools/publish_toolstate.py" "$GIT_COMMIT" \ "$GIT_COMMIT_MSG" \ "$MESSAGE_FILE" \ diff --git a/src/doc/index.md b/src/doc/index.md index 0a2a80e8fd6e2..2d10230ffcf7a 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -120,7 +120,7 @@ Rust. It's also sometimes called "the 'nomicon." ## The `rustc` Contribution Guide -[The `rustc` Guide](https://rust-lang.github.io/rustc-guide/) documents how +[The `rustc` Guide](https://rustc-dev-guide.rust-lang.org/) documents how the compiler works and how to contribute to it. This is useful if you want to build or modify the Rust compiler from source (e.g. to target something non-standard). diff --git a/src/doc/rustc/src/contributing.md b/src/doc/rustc/src/contributing.md index 25a5c97b0a120..3b552e7cc0a74 100644 --- a/src/doc/rustc/src/contributing.md +++ b/src/doc/rustc/src/contributing.md @@ -1,12 +1,12 @@ # Contributing to rustc We'd love to have your help improving `rustc`! To that end, we've written [a -whole book][rustc_guide] on its +whole book][rustc_dev_guide] on its internals, how it works, and how to get started working on it. To learn more, you'll want to check that out. If you would like to contribute to _this_ book, you can find its source in the rustc source at [src/doc/rustc][rustc_book]. -[rustc_guide]: https://rust-lang.github.io/rustc-guide/ +[rustc_dev_guide]: https://rustc-dev-guide.rust-lang.org/ [rustc_book]: https://github.com/rust-lang/rust/tree/master/src/doc/rustc diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index 5ef673009bb6d..52d8349bc9a87 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -2,8 +2,6 @@ use crate::fmt::{Debug, Display, Formatter, LowerExp, Result, UpperExp}; use crate::mem::MaybeUninit; use crate::num::flt2dec; -// ignore-tidy-undocumented-unsafe - // Don't inline this so callers don't use the stack space this function // requires unless they have to. #[inline(never)] @@ -16,6 +14,7 @@ fn float_to_decimal_common_exact<T>( where T: flt2dec::DecodableFloat, { + // SAFETY: Possible undefined behavior, see FIXME(#53491) unsafe { let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64 let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 4]>::uninit(); @@ -48,6 +47,7 @@ fn float_to_decimal_common_shortest<T>( where T: flt2dec::DecodableFloat, { + // SAFETY: Possible undefined behavior, see FIXME(#53491) unsafe { // enough for f32 and f64 let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit(); @@ -103,6 +103,7 @@ fn float_to_exponential_common_exact<T>( where T: flt2dec::DecodableFloat, { + // SAFETY: Possible undefined behavior, see FIXME(#53491) unsafe { let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64 let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 6]>::uninit(); @@ -132,6 +133,7 @@ fn float_to_exponential_common_shortest<T>( where T: flt2dec::DecodableFloat, { + // SAFETY: Possible undefined behavior, see FIXME(#53491) unsafe { // enough for f32 and f64 let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit(); diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index d2cebf593ab09..a93b34fc46cb9 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1,7 +1,5 @@ //! Utilities for formatting and printing strings. -// ignore-tidy-undocumented-unsafe - #![stable(feature = "rust1", since = "1.0.0")] use crate::cell::{Cell, Ref, RefCell, RefMut, UnsafeCell}; @@ -281,6 +279,14 @@ impl<'a> ArgumentV1<'a> { #[doc(hidden)] #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] pub fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter<'_>) -> Result) -> ArgumentV1<'b> { + // SAFETY: `mem::transmute(x)` is safe because + // 1. `&'b T` keeps the lifetime it originated with `'b` + // (so as to not have an unbounded lifetime) + // 2. `&'b T` and `&'b Void` have the same memory layout + // (when `T` is `Sized`, as it is here) + // `mem::transmute(f)` is safe since `fn(&T, &mut Formatter<'_>) -> Result` + // and `fn(&Void, &mut Formatter<'_>) -> Result` have the same ABI + // (as long as `T` is `Sized`) unsafe { ArgumentV1 { formatter: mem::transmute(f), value: mem::transmute(x) } } } @@ -1399,6 +1405,14 @@ impl<'a> Formatter<'a> { fn write_formatted_parts(&mut self, formatted: &flt2dec::Formatted<'_>) -> Result { fn write_bytes(buf: &mut dyn Write, s: &[u8]) -> Result { + // SAFETY: This is used for `flt2dec::Part::Num` and `flt2dec::Part::Copy`. + // It's safe to use for `flt2dec::Part::Num` since every char `c` is between + // `b'0'` and `b'9'`, which means `s` is valid UTF-8. + // It's also probably safe in practice to use for `flt2dec::Part::Copy(buf)` + // since `buf` should be plain ASCII, but it's possible for someone to pass + // in a bad value for `buf` into `flt2dec::to_shortest_str` since it is a + // public function. + // FIXME: Determine whether this could result in UB. buf.write_str(unsafe { str::from_utf8_unchecked(s) }) } diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 5dfd3a8ecdbd6..7d77e33d74378 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -1,7 +1,5 @@ //! Integer and floating-point number formatting -// ignore-tidy-undocumented-unsafe - use crate::fmt; use crate::mem::MaybeUninit; use crate::num::flt2dec; @@ -84,6 +82,8 @@ trait GenericRadix { } } let buf = &buf[curr..]; + // SAFETY: The only chars in `buf` are created by `Self::digit` which are assumed to be + // valid UTF-8 let buf = unsafe { str::from_utf8_unchecked(slice::from_raw_parts(MaybeUninit::first_ptr(buf), buf.len())) }; @@ -189,11 +189,19 @@ static DEC_DIGITS_LUT: &[u8; 200] = b"0001020304050607080910111213141516171819\ macro_rules! impl_Display { ($($t:ident),* as $u:ident via $conv_fn:ident named $name:ident) => { fn $name(mut n: $u, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // 2^128 is about 3*10^38, so 39 gives an extra byte of space let mut buf = [MaybeUninit::<u8>::uninit(); 39]; let mut curr = buf.len() as isize; let buf_ptr = MaybeUninit::first_ptr_mut(&mut buf); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); + // SAFETY: Since `d1` and `d2` are always less than or equal to `198`, we + // can copy from `lut_ptr[d1..d1 + 1]` and `lut_ptr[d2..d2 + 1]`. To show + // that it's OK to copy into `buf_ptr`, notice that at the beginning + // `curr == buf.len() == 39 > log(n)` since `n < 2^128 < 10^39`, and at + // each step this is kept the same as `n` is divided. Since `n` is always + // non-negative, this means that `curr > 0` so `buf_ptr[curr..curr + 1]` + // is safe to access. unsafe { // need at least 16 bits for the 4-characters-at-a-time to work. assert!(crate::mem::size_of::<$u>() >= 2); @@ -206,6 +214,10 @@ macro_rules! impl_Display { let d1 = (rem / 100) << 1; let d2 = (rem % 100) << 1; curr -= 4; + + // We are allowed to copy to `buf_ptr[curr..curr + 3]` here since + // otherwise `curr < 0`. But then `n` was originally at least `10000^10` + // which is `10^40 > 2^128 > n`. ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2); ptr::copy_nonoverlapping(lut_ptr.offset(d2), buf_ptr.offset(curr + 2), 2); } @@ -232,6 +244,8 @@ macro_rules! impl_Display { } } + // SAFETY: `curr` > 0 (since we made `buf` large enough), and all the chars are valid + // UTF-8 since `DEC_DIGITS_LUT` is let buf_slice = unsafe { str::from_utf8_unchecked( slice::from_raw_parts(buf_ptr.offset(curr), buf.len() - curr as usize)) @@ -304,6 +318,8 @@ macro_rules! impl_Exp { }; // 39 digits (worst case u128) + . = 40 + // Since `curr` always decreases by the number of digits copied, this means + // that `curr >= 0`. let mut buf = [MaybeUninit::<u8>::uninit(); 40]; let mut curr = buf.len() as isize; //index for buf let buf_ptr = MaybeUninit::first_ptr_mut(&mut buf); @@ -313,6 +329,8 @@ macro_rules! impl_Exp { while n >= 100 { let d1 = ((n % 100) as isize) << 1; curr -= 2; + // SAFETY: `d1 <= 198`, so we can copy from `lut_ptr[d1..d1 + 2]` since + // `DEC_DIGITS_LUT` has a length of 200. unsafe { ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2); } @@ -324,6 +342,7 @@ macro_rules! impl_Exp { // decode second-to-last character if n >= 10 { curr -= 1; + // SAFETY: Safe since `40 > curr >= 0` (see comment) unsafe { *buf_ptr.offset(curr) = (n as u8 % 10_u8) + b'0'; } @@ -333,11 +352,13 @@ macro_rules! impl_Exp { // add decimal point iff >1 mantissa digit will be printed if exponent != trailing_zeros || added_precision != 0 { curr -= 1; + // SAFETY: Safe since `40 > curr >= 0` unsafe { *buf_ptr.offset(curr) = b'.'; } } + // SAFETY: Safe since `40 > curr >= 0` let buf_slice = unsafe { // decode last character curr -= 1; @@ -350,6 +371,8 @@ macro_rules! impl_Exp { // stores 'e' (or 'E') and the up to 2-digit exponent let mut exp_buf = [MaybeUninit::<u8>::uninit(); 3]; let exp_ptr = MaybeUninit::first_ptr_mut(&mut exp_buf); + // SAFETY: In either case, `exp_buf` is written within bounds and `exp_ptr[..len]` + // is contained within `exp_buf` since `len <= 3`. let exp_slice = unsafe { *exp_ptr.offset(0) = if upper {b'E'} else {b'e'}; let len = if exponent < 10 { diff --git a/src/librustc/README.md b/src/librustc/README.md index c0e5c542bdc8b..de58f546cd3b5 100644 --- a/src/librustc/README.md +++ b/src/librustc/README.md @@ -1,3 +1,3 @@ -For more information about how rustc works, see the [rustc guide]. +For more information about how rustc works, see the [rustc dev guide]. -[rustc guide]: https://rust-lang.github.io/rustc-guide/ +[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ diff --git a/src/librustc/dep_graph/README.md b/src/librustc/dep_graph/README.md index 91a06e452e5fd..b9d91cd35a8dd 100644 --- a/src/librustc/dep_graph/README.md +++ b/src/librustc/dep_graph/README.md @@ -1,4 +1,4 @@ To learn more about how dependency tracking works in rustc, see the [rustc guide]. -[rustc guide]: https://rust-lang.github.io/rustc-guide/query.html +[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/query.html diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index d5cde7034116c..a2dc1fdb34b78 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -174,7 +174,7 @@ impl DepGraph { /// what state they have access to. In particular, we want to /// prevent implicit 'leaks' of tracked state into the task (which /// could then be read without generating correct edges in the - /// dep-graph -- see the [rustc guide] for more details on + /// dep-graph -- see the [rustc dev guide] for more details on /// the dep-graph). To this end, the task function gets exactly two /// pieces of state: the context `cx` and an argument `arg`. Both /// of these bits of state must be of some type that implements @@ -194,7 +194,7 @@ impl DepGraph { /// - If you need 3+ arguments, use a tuple for the /// `arg` parameter. /// - /// [rustc guide]: https://rust-lang.github.io/rustc-guide/incremental-compilation.html + /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/incremental-compilation.html pub fn with_task<'a, C, A, R>( &self, key: DepNode, diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 1aa3b27bd1a5d..30c9a2ee769fb 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1,6 +1,6 @@ -//! HIR datatypes. See the [rustc guide] for more info. +//! HIR datatypes. See the [rustc dev guide] for more info. //! -//! [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html +//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html pub mod exports; pub mod map; diff --git a/src/librustc/infer/canonical.rs b/src/librustc/infer/canonical.rs index 76d0d57e233a3..5f7e8c849653c 100644 --- a/src/librustc/infer/canonical.rs +++ b/src/librustc/infer/canonical.rs @@ -17,9 +17,9 @@ //! `instantiate_query_result` method. //! //! For a more detailed look at what is happening here, check -//! out the [chapter in the rustc guide][c]. +//! out the [chapter in the rustc dev guide][c]. //! -//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html +//! [c]: https://rustc-dev-guide.rust-lang.org/traits/canonicalization.html use crate::infer::MemberConstraint; use crate::ty::subst::GenericArg; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 055d70effc6e6..24237235e0c4a 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -14,9 +14,9 @@ //! (or `tcx`), which is the central context during most of //! compilation, containing the interners and other things. //! -//! For more information about how rustc works, see the [rustc guide]. +//! For more information about how rustc works, see the [rustc dev guide]. //! -//! [rustc guide]: https://rust-lang.github.io/rustc-guide/ +//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ //! //! # Note //! diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 1d043f5dcdefa..758ba4a1ab013 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -2,9 +2,9 @@ //! the parent links in the region hierarchy. //! //! For more information about how MIR-based region-checking works, -//! see the [rustc guide]. +//! see the [rustc dev guide]. //! -//! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html +//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/borrowck.html use crate::ich::{NodeIdHashingMode, StableHashingContext}; use crate::ty::{self, DefIdTree, TyCtxt}; diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index b2413f5a2c83f..afb585c4aa339 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1,6 +1,6 @@ -//! MIR datatypes and passes. See the [rustc guide] for more info. +//! MIR datatypes and passes. See the [rustc dev guide] for more info. //! -//! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/index.html +//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html use crate::mir::interpret::{GlobalAlloc, Scalar}; use crate::mir::visit::MirVisitable; diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 4e02a1744ff34..6ebcc8b075462 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -1,6 +1,6 @@ -//! Trait Resolution. See the [rustc guide] for more information on how this works. +//! Trait Resolution. See the [rustc dev guide] for more information on how this works. //! -//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html +//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html pub mod query; pub mod select; diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index ac3d0049c0c7c..08d78b3a0b24b 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1,6 +1,6 @@ -//! Candidate selection. See the [rustc guide] for more information on how this works. +//! Candidate selection. See the [rustc dev guide] for more information on how this works. //! -//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html#selection +//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html#selection use self::EvaluationResult::*; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 48ef81c1d5bf7..5c32bdad21b48 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -916,9 +916,9 @@ pub struct FreeRegionInfo { /// The central data structure of the compiler. It stores references /// to the various **arenas** and also houses the results of the /// various **compiler queries** that have been performed. See the -/// [rustc guide] for more details. +/// [rustc dev guide] for more details. /// -/// [rustc guide]: https://rust-lang.github.io/rustc-guide/ty.html +/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ty.html #[derive(Copy, Clone)] #[rustc_diagnostic_item = "TyCtxt"] pub struct TyCtxt<'tcx> { diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index dedb3035cedb3..f616d81603775 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -782,8 +782,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { present_first @ Some(_) => present_first, // Uninhabited because it has no variants, or only absent ones. None if def.is_enum() => return tcx.layout_raw(param_env.and(tcx.types.never)), - // if it's a struct, still compute a layout so that we can still compute the - // field offsets + // If it's a struct, still compute a layout so that we can still compute the + // field offsets. None => Some(VariantIdx::new(0)), }; @@ -1990,7 +1990,15 @@ where { fn for_variant(this: TyLayout<'tcx>, cx: &C, variant_index: VariantIdx) -> TyLayout<'tcx> { let details = match this.variants { - Variants::Single { index } if index == variant_index => this.details, + Variants::Single { index } + // If all variants but one are uninhabited, the variant layout is the enum layout. + if index == variant_index && + // Don't confuse variants of uninhabited enums with the enum itself. + // For more details see https://github.com/rust-lang/rust/issues/69763. + this.fields != FieldPlacement::Union(0) => + { + this.details + } Variants::Single { index } => { // Deny calling for_variant more than once for non-Single enums. diff --git a/src/librustc/ty/query/README.md b/src/librustc/ty/query/README.md index 4b5e08cecd99c..8ec07b9fdeb78 100644 --- a/src/librustc/ty/query/README.md +++ b/src/librustc/ty/query/README.md @@ -1,3 +1,3 @@ -For more information about how the query system works, see the [rustc guide]. +For more information about how the query system works, see the [rustc dev guide]. -[rustc guide]: https://rust-lang.github.io/rustc-guide/query.html +[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/query.html diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 47bf7822b1f55..76b9aed831482 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1396,11 +1396,11 @@ pub type Region<'tcx> = &'tcx RegionKind; /// the inference variable is supposed to satisfy the relation /// *for every value of the placeholder region*. To ensure that doesn't /// happen, you can use `leak_check`. This is more clearly explained -/// by the [rustc guide]. +/// by the [rustc dev guide]. /// /// [1]: http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/ /// [2]: http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/ -/// [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/hrtb.html +/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html #[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable, PartialOrd, Ord)] pub enum RegionKind { /// Region bound in a type or fn declaration which will be diff --git a/src/librustc_ast/README.md b/src/librustc_ast/README.md index d62e5a5ece0bf..dd407dba1f4cc 100644 --- a/src/librustc_ast/README.md +++ b/src/librustc_ast/README.md @@ -3,7 +3,7 @@ The `rustc_ast` crate contains those things concerned purely with syntax lexer, macro expander, and utilities for traversing ASTs. For more information about how these things work in rustc, see the -rustc guide: +rustc dev guide: -- [Parsing](https://rust-lang.github.io/rustc-guide/the-parser.html) -- [Macro Expansion](https://rust-lang.github.io/rustc-guide/macro-expansion.html) +- [Parsing](https://rustc-dev-guide.rust-lang.org/the-parser.html) +- [Macro Expansion](https://rustc-dev-guide.rust-lang.org/macro-expansion.html) diff --git a/src/librustc_ast/ast.rs b/src/librustc_ast/ast.rs index 88a96dc6c6966..b139815188318 100644 --- a/src/librustc_ast/ast.rs +++ b/src/librustc_ast/ast.rs @@ -2153,7 +2153,7 @@ impl FnRetTy { /// Module declaration. /// /// E.g., `mod foo;` or `mod foo { .. }`. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default)] pub struct Mod { /// A span from the first token past `{` to the last token until `}`. /// For `mod foo;`, the inner span ranges from the first token diff --git a/src/librustc_builtin_macros/source_util.rs b/src/librustc_builtin_macros/source_util.rs index 5ad72a7443dd2..662bbe6a287a3 100644 --- a/src/librustc_builtin_macros/source_util.rs +++ b/src/librustc_builtin_macros/source_util.rs @@ -5,7 +5,7 @@ use rustc_ast::tokenstream::TokenStream; use rustc_ast_pretty::pprust; use rustc_expand::base::{self, *}; use rustc_expand::panictry; -use rustc_parse::{self, new_sub_parser_from_file, parser::Parser, DirectoryOwnership}; +use rustc_parse::{self, new_sub_parser_from_file, parser::Parser}; use rustc_session::lint::builtin::INCOMPLETE_INCLUDE; use rustc_span::symbol::Symbol; use rustc_span::{self, Pos, Span}; @@ -108,8 +108,7 @@ pub fn expand_include<'cx>( return DummyResult::any(sp); } }; - let directory_ownership = DirectoryOwnership::Owned { relative: None }; - let p = new_sub_parser_from_file(cx.parse_sess(), &file, directory_ownership, None, sp); + let p = new_sub_parser_from_file(cx.parse_sess(), &file, None, sp); struct ExpandResult<'a> { p: Parser<'a>, diff --git a/src/librustc_codegen_llvm/README.md b/src/librustc_codegen_llvm/README.md index dda2e5ac18f01..97d8f76623e93 100644 --- a/src/librustc_codegen_llvm/README.md +++ b/src/librustc_codegen_llvm/README.md @@ -2,6 +2,6 @@ The `codegen` crate contains the code to convert from MIR into LLVM IR, and then from LLVM IR into machine code. In general it contains code that runs towards the end of the compilation process. -For more information about how codegen works, see the [rustc guide]. +For more information about how codegen works, see the [rustc dev guide]. -[rustc guide]: https://rust-lang.github.io/rustc-guide/codegen.html +[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/codegen.html diff --git a/src/librustc_codegen_ssa/README.md b/src/librustc_codegen_ssa/README.md index 2a3a4fcc5fca4..90d991a3a4b25 100644 --- a/src/librustc_codegen_ssa/README.md +++ b/src/librustc_codegen_ssa/README.md @@ -1,3 +1,3 @@ -Please read the rustc-guide chapter on [Backend Agnostic Codegen][bac]. +Please read the rustc-dev-guide chapter on [Backend Agnostic Codegen][bac]. -[bac]: https://rust-lang.github.io/rustc-guide/codegen/backend-agnostic.html +[bac]: https://rustc-dev-guide.rust-lang.org/codegen/backend-agnostic.html diff --git a/src/librustc_driver/README.md b/src/librustc_driver/README.md index c4d73953e9b2e..37dc7f6ba5fe4 100644 --- a/src/librustc_driver/README.md +++ b/src/librustc_driver/README.md @@ -5,6 +5,6 @@ not contain any of the "main logic" of the compiler (though it does have some code related to pretty printing or other minor compiler options). -For more information about how the driver works, see the [rustc guide]. +For more information about how the driver works, see the [rustc dev guide]. -[rustc guide]: https://rust-lang.github.io/rustc-guide/rustc-driver.html +[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/rustc-driver.html diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs index f15e626c2783b..313ff88005295 100644 --- a/src/librustc_expand/base.rs +++ b/src/librustc_expand/base.rs @@ -1,4 +1,5 @@ use crate::expand::{self, AstFragment, Invocation}; +use crate::module::DirectoryOwnership; use rustc_ast::ast::{self, Attribute, Name, NodeId, PatKind}; use rustc_ast::mut_visit::{self, MutVisitor}; @@ -10,7 +11,7 @@ use rustc_attr::{self as attr, Deprecation, HasAttrs, Stability}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{self, Lrc}; use rustc_errors::{DiagnosticBuilder, DiagnosticId}; -use rustc_parse::{self, parser, DirectoryOwnership, MACRO_ARGUMENTS}; +use rustc_parse::{self, parser, MACRO_ARGUMENTS}; use rustc_session::parse::ParseSess; use rustc_span::edition::Edition; use rustc_span::hygiene::{AstPass, ExpnData, ExpnId, ExpnKind}; diff --git a/src/librustc_parse/config.rs b/src/librustc_expand/config.rs similarity index 95% rename from src/librustc_parse/config.rs rename to src/librustc_expand/config.rs index f42091e7c296a..1cdd35b52af60 100644 --- a/src/librustc_parse/config.rs +++ b/src/librustc_expand/config.rs @@ -1,14 +1,5 @@ -//! Process the potential `cfg` attributes on a module. -//! Also determine if the module should be included in this configuration. -//! -//! This module properly belongs in rustc_expand, but for now it's tied into -//! parsing, so we leave it here to avoid complicated out-of-line dependencies. -//! -//! A principled solution to this wrong location would be to implement [#64197]. -//! -//! [#64197]: https://github.com/rust-lang/rust/issues/64197 - -use crate::{parse_in, validate_attr}; +//! Conditional compilation stripping. + use rustc_ast::ast::{self, AttrItem, Attribute, MetaItem}; use rustc_ast::attr::HasAttrs; use rustc_ast::mut_visit::*; @@ -21,6 +12,7 @@ use rustc_feature::{Feature, Features, State as FeatureState}; use rustc_feature::{ ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES, STABLE_REMOVED_FEATURES, }; +use rustc_parse::{parse_in, validate_attr}; use rustc_session::parse::{feature_err, ParseSess}; use rustc_span::edition::{Edition, ALL_EDITIONS}; use rustc_span::symbol::{sym, Symbol}; @@ -538,12 +530,3 @@ impl<'a> MutVisitor for StripUnconfigured<'a> { fn is_cfg(attr: &Attribute) -> bool { attr.check_name(sym::cfg) } - -/// Process the potential `cfg` attributes on a module. -/// Also determine if the module should be included in this configuration. -pub fn process_configure_mod(sess: &ParseSess, cfg_mods: bool, attrs: &mut Vec<Attribute>) -> bool { - // Don't perform gated feature checking. - let mut strip_unconfigured = StripUnconfigured { sess, features: None }; - strip_unconfigured.process_cfg_attrs(attrs); - !cfg_mods || strip_unconfigured.in_cfg(&attrs) -} diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index effa89e8bfb21..be92bd6cff398 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -1,7 +1,9 @@ use crate::base::*; use crate::config::StripUnconfigured; +use crate::configure; use crate::hygiene::{ExpnData, ExpnId, ExpnKind, SyntaxContext}; use crate::mbe::macro_rules::annotate_err_with_kind; +use crate::module::{parse_external_mod, push_directory, Directory, DirectoryOwnership}; use crate::placeholders::{placeholder, PlaceholderExpander}; use crate::proc_macro::collect_derives; @@ -17,10 +19,8 @@ use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, is_builtin_attr, HasAttrs}; use rustc_errors::{Applicability, FatalError, PResult}; use rustc_feature::Features; -use rustc_parse::configure; use rustc_parse::parser::Parser; use rustc_parse::validate_attr; -use rustc_parse::DirectoryOwnership; use rustc_session::lint::builtin::UNUSED_DOC_COMMENTS; use rustc_session::lint::BuiltinLintDiagnostics; use rustc_session::parse::{feature_err, ParseSess}; @@ -1359,59 +1359,72 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { .make_items(); } + let mut attrs = mem::take(&mut item.attrs); // We do this to please borrowck. + let ident = item.ident; + let span = item.span; + match item.kind { ast::ItemKind::Mac(..) => { + item.attrs = attrs; self.check_attributes(&item.attrs); item.and_then(|item| match item.kind { ItemKind::Mac(mac) => self - .collect( - AstFragmentKind::Items, - InvocationKind::Bang { mac, span: item.span }, - ) + .collect(AstFragmentKind::Items, InvocationKind::Bang { mac, span }) .make_items(), _ => unreachable!(), }) } - ast::ItemKind::Mod(ast::Mod { inner, inline, .. }) - if item.ident != Ident::invalid() => - { - let orig_directory_ownership = self.cx.current_expansion.directory_ownership; + ast::ItemKind::Mod(ref mut old_mod @ ast::Mod { .. }) if ident != Ident::invalid() => { + let sess = self.cx.parse_sess; + let orig_ownership = self.cx.current_expansion.directory_ownership; let mut module = (*self.cx.current_expansion.module).clone(); - module.mod_path.push(item.ident); - if inline { - if let Some(path) = attr::first_attr_value_str_by_name(&item.attrs, sym::path) { - self.cx.current_expansion.directory_ownership = - DirectoryOwnership::Owned { relative: None }; - module.directory.push(&*path.as_str()); - } else { - module.directory.push(&*item.ident.as_str()); - } + let pushed = &mut false; // Record `parse_external_mod` pushing so we can pop. + let dir = Directory { ownership: orig_ownership, path: module.directory }; + let Directory { ownership, path } = if old_mod.inline { + // Inline `mod foo { ... }`, but we still need to push directories. + item.attrs = attrs; + push_directory(ident, &item.attrs, dir) } else { - let path = self.cx.parse_sess.source_map().span_to_unmapped_path(inner); - let mut path = match path { - FileName::Real(path) => path, - other => PathBuf::from(other.to_string()), - }; - let directory_ownership = match path.file_name().unwrap().to_str() { - Some("mod.rs") => DirectoryOwnership::Owned { relative: None }, - Some(_) => DirectoryOwnership::Owned { relative: Some(item.ident) }, - None => DirectoryOwnership::UnownedViaMod, + // We have an outline `mod foo;` so we need to parse the file. + let (new_mod, dir) = + parse_external_mod(sess, ident, span, dir, &mut attrs, pushed); + *old_mod = new_mod; + item.attrs = attrs; + // File can have inline attributes, e.g., `#![cfg(...)]` & co. => Reconfigure. + item = match self.configure(item) { + Some(node) => node, + None => { + if *pushed { + sess.included_mod_stack.borrow_mut().pop(); + } + return Default::default(); + } }; - path.pop(); - module.directory = path; - self.cx.current_expansion.directory_ownership = directory_ownership; - } + dir + }; + // Set the module info before we flat map. + self.cx.current_expansion.directory_ownership = ownership; + module.directory = path; + module.mod_path.push(ident); let orig_module = mem::replace(&mut self.cx.current_expansion.module, Rc::new(module)); + let result = noop_flat_map_item(item, self); + + // Restore the module info. self.cx.current_expansion.module = orig_module; - self.cx.current_expansion.directory_ownership = orig_directory_ownership; + self.cx.current_expansion.directory_ownership = orig_ownership; + if *pushed { + sess.included_mod_stack.borrow_mut().pop(); + } result } - - _ => noop_flat_map_item(item, self), + _ => { + item.attrs = attrs; + noop_flat_map_item(item, self) + } } } diff --git a/src/librustc_expand/lib.rs b/src/librustc_expand/lib.rs index f119c956ced04..0320a275e5d20 100644 --- a/src/librustc_expand/lib.rs +++ b/src/librustc_expand/lib.rs @@ -1,9 +1,11 @@ +#![feature(bool_to_option)] #![feature(cow_is_borrowed)] #![feature(crate_visibility_modifier)] #![feature(decl_macro)] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_internals)] #![feature(proc_macro_span)] +#![feature(try_blocks)] extern crate proc_macro as pm; @@ -33,8 +35,10 @@ pub use mbe::macro_rules::compile_declarative_macro; crate use rustc_span::hygiene; pub mod base; pub mod build; +#[macro_use] +pub mod config; pub mod expand; -pub use rustc_parse::config; +pub mod module; pub mod proc_macro; crate mod mbe; diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index 3040a9aefbb30..a6b58e885be47 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -1,4 +1,4 @@ -use crate::base::{DummyResult, ExpansionData, ExtCtxt, MacResult, TTMacroExpander}; +use crate::base::{DummyResult, ExtCtxt, MacResult, TTMacroExpander}; use crate::base::{SyntaxExtension, SyntaxExtensionKind}; use crate::expand::{ensure_complete_parse, parse_ast_fragment, AstFragment, AstFragmentKind}; use crate::mbe; @@ -18,7 +18,6 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, DiagnosticBuilder, FatalError}; use rustc_feature::Features; use rustc_parse::parser::Parser; -use rustc_parse::Directory; use rustc_session::parse::ParseSess; use rustc_span::edition::Edition; use rustc_span::hygiene::Transparency; @@ -182,6 +181,8 @@ fn generic_extension<'cx>( lhses: &[mbe::TokenTree], rhses: &[mbe::TokenTree], ) -> Box<dyn MacResult + 'cx> { + let sess = cx.parse_sess; + if cx.trace_macros() { let msg = format!("expanding `{}! {{ {} }}`", name, pprust::tts_to_string(arg.clone())); trace_macros_note(&mut cx.expansions, sp, msg); @@ -209,7 +210,7 @@ fn generic_extension<'cx>( // hacky, but speeds up the `html5ever` benchmark significantly. (Issue // 68836 suggests a more comprehensive but more complex change to deal with // this situation.) - let parser = parser_from_cx(&cx.current_expansion, &cx.parse_sess, arg.clone()); + let parser = parser_from_cx(sess, arg.clone()); for (i, lhs) in lhses.iter().enumerate() { // try each arm's matchers @@ -222,14 +223,13 @@ fn generic_extension<'cx>( // This is used so that if a matcher is not `Success(..)`ful, // then the spans which became gated when parsing the unsuccessful matcher // are not recorded. On the first `Success(..)`ful matcher, the spans are merged. - let mut gated_spans_snapshot = - mem::take(&mut *cx.parse_sess.gated_spans.spans.borrow_mut()); + let mut gated_spans_snapshot = mem::take(&mut *sess.gated_spans.spans.borrow_mut()); match parse_tt(&mut Cow::Borrowed(&parser), lhs_tt) { Success(named_matches) => { // The matcher was `Success(..)`ful. // Merge the gated spans from parsing the matcher with the pre-existing ones. - cx.parse_sess.gated_spans.merge(gated_spans_snapshot); + sess.gated_spans.merge(gated_spans_snapshot); let rhs = match rhses[i] { // ignore delimiters @@ -258,11 +258,7 @@ fn generic_extension<'cx>( trace_macros_note(&mut cx.expansions, sp, msg); } - let directory = Directory { - path: cx.current_expansion.module.directory.clone(), - ownership: cx.current_expansion.directory_ownership, - }; - let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), true, false, None); + let mut p = Parser::new(sess, tts, false, None); p.root_module_name = cx.current_expansion.module.mod_path.last().map(|id| id.to_string()); p.last_type_ascription = cx.current_expansion.prior_type_ascription; @@ -289,7 +285,7 @@ fn generic_extension<'cx>( // The matcher was not `Success(..)`ful. // Restore to the state before snapshotting and maybe try again. - mem::swap(&mut gated_spans_snapshot, &mut cx.parse_sess.gated_spans.spans.borrow_mut()); + mem::swap(&mut gated_spans_snapshot, &mut sess.gated_spans.spans.borrow_mut()); } drop(parser); @@ -309,8 +305,7 @@ fn generic_extension<'cx>( mbe::TokenTree::Delimited(_, ref delim) => &delim.tts[..], _ => continue, }; - let parser = parser_from_cx(&cx.current_expansion, &cx.parse_sess, arg.clone()); - match parse_tt(&mut Cow::Borrowed(&parser), lhs_tt) { + match parse_tt(&mut Cow::Borrowed(&parser_from_cx(sess, arg.clone())), lhs_tt) { Success(_) => { if comma_span.is_dummy() { err.note("you might be missing a comma"); @@ -392,7 +387,7 @@ pub fn compile_declarative_macro( ), ]; - let parser = Parser::new(sess, body, None, true, true, rustc_parse::MACRO_ARGUMENTS); + let parser = Parser::new(sess, body, true, rustc_parse::MACRO_ARGUMENTS); let argument_map = match parse_tt(&mut Cow::Borrowed(&parser), &argument_gram) { Success(m) => m, Failure(token, msg) => { @@ -1209,16 +1204,8 @@ fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String { } } -fn parser_from_cx<'cx>( - current_expansion: &'cx ExpansionData, - sess: &'cx ParseSess, - tts: TokenStream, -) -> Parser<'cx> { - let directory = Directory { - path: current_expansion.module.directory.clone(), - ownership: current_expansion.directory_ownership, - }; - Parser::new(sess, tts, Some(directory), true, true, rustc_parse::MACRO_ARGUMENTS) +fn parser_from_cx(sess: &ParseSess, tts: TokenStream) -> Parser<'_> { + Parser::new(sess, tts, true, rustc_parse::MACRO_ARGUMENTS) } /// Generates an appropriate parsing failure message. For EOF, this is "unexpected end...". For diff --git a/src/librustc_expand/module.rs b/src/librustc_expand/module.rs new file mode 100644 index 0000000000000..99f52e694627e --- /dev/null +++ b/src/librustc_expand/module.rs @@ -0,0 +1,307 @@ +use rustc_ast::ast::{self, Attribute, Ident, Mod}; +use rustc_ast::{attr, token}; +use rustc_errors::{struct_span_err, PResult}; +use rustc_parse::new_sub_parser_from_file; +use rustc_session::parse::ParseSess; +use rustc_span::source_map::{FileName, Span}; +use rustc_span::symbol::sym; + +use std::path::{self, Path, PathBuf}; + +#[derive(Clone)] +pub struct Directory { + pub path: PathBuf, + pub ownership: DirectoryOwnership, +} + +#[derive(Copy, Clone)] +pub enum DirectoryOwnership { + Owned { + // None if `mod.rs`, `Some("foo")` if we're in `foo.rs`. + relative: Option<ast::Ident>, + }, + UnownedViaBlock, + UnownedViaMod, +} + +/// Information about the path to a module. +// Public for rustfmt usage. +pub struct ModulePath<'a> { + name: String, + path_exists: bool, + pub result: PResult<'a, ModulePathSuccess>, +} + +// Public for rustfmt usage. +pub struct ModulePathSuccess { + pub path: PathBuf, + pub ownership: DirectoryOwnership, +} + +crate fn parse_external_mod( + sess: &ParseSess, + id: ast::Ident, + span: Span, // The span to blame on errors. + Directory { mut ownership, path }: Directory, + attrs: &mut Vec<Attribute>, + pop_mod_stack: &mut bool, +) -> (Mod, Directory) { + // We bail on the first error, but that error does not cause a fatal error... (1) + let result: PResult<'_, _> = try { + // Extract the file path and the new ownership. + let mp = submod_path(sess, id, span, &attrs, ownership, &path)?; + ownership = mp.ownership; + + // Ensure file paths are acyclic. + let mut included_mod_stack = sess.included_mod_stack.borrow_mut(); + error_on_circular_module(sess, span, &mp.path, &included_mod_stack)?; + included_mod_stack.push(mp.path.clone()); + *pop_mod_stack = true; // We have pushed, so notify caller. + drop(included_mod_stack); + + // Actually parse the external file as amodule. + let mut p0 = new_sub_parser_from_file(sess, &mp.path, Some(id.to_string()), span); + let mut module = p0.parse_mod(&token::Eof)?; + module.0.inline = false; + module + }; + // (1) ...instead, we return a dummy module. + let (module, mut new_attrs) = result.map_err(|mut err| err.emit()).unwrap_or_default(); + attrs.append(&mut new_attrs); + + // Extract the directory path for submodules of `module`. + let path = sess.source_map().span_to_unmapped_path(module.inner); + let mut path = match path { + FileName::Real(path) => path, + other => PathBuf::from(other.to_string()), + }; + path.pop(); + + (module, Directory { ownership, path }) +} + +fn error_on_circular_module<'a>( + sess: &'a ParseSess, + span: Span, + path: &Path, + included_mod_stack: &[PathBuf], +) -> PResult<'a, ()> { + if let Some(i) = included_mod_stack.iter().position(|p| *p == path) { + let mut err = String::from("circular modules: "); + for p in &included_mod_stack[i..] { + err.push_str(&p.to_string_lossy()); + err.push_str(" -> "); + } + err.push_str(&path.to_string_lossy()); + return Err(sess.span_diagnostic.struct_span_err(span, &err[..])); + } + Ok(()) +} + +crate fn push_directory( + id: Ident, + attrs: &[Attribute], + Directory { mut ownership, mut path }: Directory, +) -> Directory { + if let Some(filename) = attr::first_attr_value_str_by_name(attrs, sym::path) { + path.push(&*filename.as_str()); + ownership = DirectoryOwnership::Owned { relative: None }; + } else { + // We have to push on the current module name in the case of relative + // paths in order to ensure that any additional module paths from inline + // `mod x { ... }` come after the relative extension. + // + // For example, a `mod z { ... }` inside `x/y.rs` should set the current + // directory path to `/x/y/z`, not `/x/z` with a relative offset of `y`. + if let DirectoryOwnership::Owned { relative } = &mut ownership { + if let Some(ident) = relative.take() { + // Remove the relative offset. + path.push(&*ident.as_str()); + } + } + path.push(&*id.as_str()); + } + Directory { ownership, path } +} + +fn submod_path<'a>( + sess: &'a ParseSess, + id: ast::Ident, + span: Span, + attrs: &[Attribute], + ownership: DirectoryOwnership, + dir_path: &Path, +) -> PResult<'a, ModulePathSuccess> { + if let Some(path) = submod_path_from_attr(attrs, dir_path) { + let ownership = match path.file_name().and_then(|s| s.to_str()) { + // All `#[path]` files are treated as though they are a `mod.rs` file. + // This means that `mod foo;` declarations inside `#[path]`-included + // files are siblings, + // + // Note that this will produce weirdness when a file named `foo.rs` is + // `#[path]` included and contains a `mod foo;` declaration. + // If you encounter this, it's your own darn fault :P + Some(_) => DirectoryOwnership::Owned { relative: None }, + _ => DirectoryOwnership::UnownedViaMod, + }; + return Ok(ModulePathSuccess { ownership, path }); + } + + let relative = match ownership { + DirectoryOwnership::Owned { relative } => relative, + DirectoryOwnership::UnownedViaBlock | DirectoryOwnership::UnownedViaMod => None, + }; + let ModulePath { path_exists, name, result } = + default_submod_path(sess, id, span, relative, dir_path); + match ownership { + DirectoryOwnership::Owned { .. } => Ok(result?), + DirectoryOwnership::UnownedViaBlock => { + let _ = result.map_err(|mut err| err.cancel()); + error_decl_mod_in_block(sess, span, path_exists, &name) + } + DirectoryOwnership::UnownedViaMod => { + let _ = result.map_err(|mut err| err.cancel()); + error_cannot_declare_mod_here(sess, span, path_exists, &name) + } + } +} + +fn error_decl_mod_in_block<'a, T>( + sess: &'a ParseSess, + span: Span, + path_exists: bool, + name: &str, +) -> PResult<'a, T> { + let msg = "Cannot declare a non-inline module inside a block unless it has a path attribute"; + let mut err = sess.span_diagnostic.struct_span_err(span, msg); + if path_exists { + let msg = format!("Maybe `use` the module `{}` instead of redeclaring it", name); + err.span_note(span, &msg); + } + Err(err) +} + +fn error_cannot_declare_mod_here<'a, T>( + sess: &'a ParseSess, + span: Span, + path_exists: bool, + name: &str, +) -> PResult<'a, T> { + let mut err = + sess.span_diagnostic.struct_span_err(span, "cannot declare a new module at this location"); + if !span.is_dummy() { + if let FileName::Real(src_path) = sess.source_map().span_to_filename(span) { + if let Some(stem) = src_path.file_stem() { + let mut dest_path = src_path.clone(); + dest_path.set_file_name(stem); + dest_path.push("mod.rs"); + err.span_note( + span, + &format!( + "maybe move this module `{}` to its own directory via `{}`", + src_path.display(), + dest_path.display() + ), + ); + } + } + } + if path_exists { + err.span_note( + span, + &format!("... or maybe `use` the module `{}` instead of possibly redeclaring it", name), + ); + } + Err(err) +} + +/// Derive a submodule path from the first found `#[path = "path_string"]`. +/// The provided `dir_path` is joined with the `path_string`. +// Public for rustfmt usage. +pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option<PathBuf> { + // Extract path string from first `#[path = "path_string"]` attribute. + let path_string = attr::first_attr_value_str_by_name(attrs, sym::path)?; + let path_string = path_string.as_str(); + + // On windows, the base path might have the form + // `\\?\foo\bar` in which case it does not tolerate + // mixed `/` and `\` separators, so canonicalize + // `/` to `\`. + #[cfg(windows)] + let path_string = path_string.replace("/", "\\"); + + Some(dir_path.join(&*path_string)) +} + +/// Returns a path to a module. +// Public for rustfmt usage. +pub fn default_submod_path<'a>( + sess: &'a ParseSess, + id: ast::Ident, + span: Span, + relative: Option<ast::Ident>, + dir_path: &Path, +) -> ModulePath<'a> { + // If we're in a foo.rs file instead of a mod.rs file, + // we need to look for submodules in + // `./foo/<id>.rs` and `./foo/<id>/mod.rs` rather than + // `./<id>.rs` and `./<id>/mod.rs`. + let relative_prefix_string; + let relative_prefix = if let Some(ident) = relative { + relative_prefix_string = format!("{}{}", ident.name, path::MAIN_SEPARATOR); + &relative_prefix_string + } else { + "" + }; + + let mod_name = id.name.to_string(); + let default_path_str = format!("{}{}.rs", relative_prefix, mod_name); + let secondary_path_str = + format!("{}{}{}mod.rs", relative_prefix, mod_name, path::MAIN_SEPARATOR); + let default_path = dir_path.join(&default_path_str); + let secondary_path = dir_path.join(&secondary_path_str); + let default_exists = sess.source_map().file_exists(&default_path); + let secondary_exists = sess.source_map().file_exists(&secondary_path); + + let result = match (default_exists, secondary_exists) { + (true, false) => Ok(ModulePathSuccess { + path: default_path, + ownership: DirectoryOwnership::Owned { relative: Some(id) }, + }), + (false, true) => Ok(ModulePathSuccess { + path: secondary_path, + ownership: DirectoryOwnership::Owned { relative: None }, + }), + (false, false) => { + let mut err = struct_span_err!( + sess.span_diagnostic, + span, + E0583, + "file not found for module `{}`", + mod_name, + ); + err.help(&format!( + "name the file either {} or {} inside the directory \"{}\"", + default_path_str, + secondary_path_str, + dir_path.display(), + )); + Err(err) + } + (true, true) => { + let mut err = struct_span_err!( + sess.span_diagnostic, + span, + E0584, + "file for module `{}` found at both {} and {}", + mod_name, + default_path_str, + secondary_path_str, + ); + err.help("delete or rename one of them to remove the ambiguity"); + Err(err) + } + }; + + ModulePath { name: mod_name, path_exists: default_exists || secondary_exists, result } +} diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index f948e22e84b10..59a770b9b9549 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -609,9 +609,9 @@ pub struct ModuleItems { /// The top-level data structure that stores the entire contents of /// the crate currently being compiled. /// -/// For more details, see the [rustc guide]. +/// For more details, see the [rustc dev guide]. /// -/// [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html +/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html #[derive(RustcEncodable, RustcDecodable, Debug)] pub struct Crate<'hir> { pub module: Mod<'hir>, diff --git a/src/librustc_hir/lib.rs b/src/librustc_hir/lib.rs index d958dfc681b00..45f806b53f50c 100644 --- a/src/librustc_hir/lib.rs +++ b/src/librustc_hir/lib.rs @@ -1,6 +1,6 @@ -//! HIR datatypes. See the [rustc guide] for more info. +//! HIR datatypes. See the [rustc dev guide] for more info. //! -//! [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html +//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html #![feature(crate_visibility_modifier)] #![feature(const_fn)] // For the unsizing cast on `&[]` diff --git a/src/librustc_incremental/persist/README.md b/src/librustc_incremental/persist/README.md index 8131d2840b49d..b01fe219e1e11 100644 --- a/src/librustc_incremental/persist/README.md +++ b/src/librustc_incremental/persist/README.md @@ -1,3 +1,3 @@ -For info on how the incremental compilation works, see the [rustc guide]. +For info on how the incremental compilation works, see the [rustc dev guide]. -[rustc guide]: https://rust-lang.github.io/rustc-guide/query.html +[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/query.html diff --git a/src/librustc_infer/infer/canonical/canonicalizer.rs b/src/librustc_infer/infer/canonical/canonicalizer.rs index 4d3f25290e1ab..964e378f7abc8 100644 --- a/src/librustc_infer/infer/canonical/canonicalizer.rs +++ b/src/librustc_infer/infer/canonical/canonicalizer.rs @@ -1,9 +1,9 @@ //! This module contains the "canonicalizer" itself. //! //! For an overview of what canonicalization is and how it fits into -//! rustc, check out the [chapter in the rustc guide][c]. +//! rustc, check out the [chapter in the rustc dev guide][c]. //! -//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html +//! [c]: https://rustc-dev-guide.rust-lang.org/traits/canonicalization.html use crate::infer::canonical::{ Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, Canonicalized, @@ -33,9 +33,9 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// with a mapping M that maps `'?0` to `'static`. /// /// To get a good understanding of what is happening here, check - /// out the [chapter in the rustc guide][c]. + /// out the [chapter in the rustc dev guide][c]. /// - /// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query + /// [c]: https://rustc-dev-guide.rust-lang.org/traits/canonicalization.html#canonicalizing-the-query pub fn canonicalize_query<V>( &self, value: &V, @@ -77,9 +77,9 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// reference to `'static` alone. /// /// To get a good understanding of what is happening here, check - /// out the [chapter in the rustc guide][c]. + /// out the [chapter in the rustc dev guide][c]. /// - /// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query-result + /// [c]: https://rustc-dev-guide.rust-lang.org/traits/canonicalization.html#canonicalizing-the-query-result pub fn canonicalize_response<V>(&self, value: &V) -> Canonicalized<'tcx, V> where V: TypeFoldable<'tcx>, diff --git a/src/librustc_infer/infer/canonical/mod.rs b/src/librustc_infer/infer/canonical/mod.rs index ba019a8cf0369..0e9593e8ea6b0 100644 --- a/src/librustc_infer/infer/canonical/mod.rs +++ b/src/librustc_infer/infer/canonical/mod.rs @@ -17,9 +17,9 @@ //! `instantiate_query_result` method. //! //! For a more detailed look at what is happening here, check -//! out the [chapter in the rustc guide][c]. +//! out the [chapter in the rustc dev guide][c]. //! -//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html +//! [c]: https://rustc-dev-guide.rust-lang.org/traits/canonicalization.html use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind}; use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVariableOriginKind}; diff --git a/src/librustc_infer/infer/canonical/query_response.rs b/src/librustc_infer/infer/canonical/query_response.rs index 966bd99787729..b6c0dc3939bff 100644 --- a/src/librustc_infer/infer/canonical/query_response.rs +++ b/src/librustc_infer/infer/canonical/query_response.rs @@ -3,9 +3,9 @@ //! encode them therein. //! //! For an overview of what canonicaliation is and how it fits into -//! rustc, check out the [chapter in the rustc guide][c]. +//! rustc, check out the [chapter in the rustc dev guide][c]. //! -//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html +//! [c]: https://rustc-dev-guide.rust-lang.org/traits/canonicalization.html use crate::infer::canonical::substitute::{substitute_value, CanonicalExt}; use crate::infer::canonical::{ @@ -196,9 +196,9 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// the query before applying this function.) /// /// To get a good understanding of what is happening here, check - /// out the [chapter in the rustc guide][c]. + /// out the [chapter in the rustc dev guide][c]. /// - /// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html#processing-the-canonicalized-query-result + /// [c]: https://rustc-dev-guide.rust-lang.org/traits/canonicalization.html#processing-the-canonicalized-query-result pub fn instantiate_query_response_and_region_obligations<R>( &self, cause: &ObligationCause<'tcx>, diff --git a/src/librustc_infer/infer/canonical/substitute.rs b/src/librustc_infer/infer/canonical/substitute.rs index 99ddedfe8815b..afef32c1ffebb 100644 --- a/src/librustc_infer/infer/canonical/substitute.rs +++ b/src/librustc_infer/infer/canonical/substitute.rs @@ -2,9 +2,9 @@ //! `Canonical<'tcx, T>`. //! //! For an overview of what canonicalization is and how it fits into -//! rustc, check out the [chapter in the rustc guide][c]. +//! rustc, check out the [chapter in the rustc dev guide][c]. //! -//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html +//! [c]: https://rustc-dev-guide.rust-lang.org/traits/canonicalization.html use crate::infer::canonical::{Canonical, CanonicalVarValues}; use rustc::ty::fold::TypeFoldable; diff --git a/src/librustc_infer/infer/higher_ranked/README.md b/src/librustc_infer/infer/higher_ranked/README.md index e7afaa5beb0a7..533d0ef7e6c4b 100644 --- a/src/librustc_infer/infer/higher_ranked/README.md +++ b/src/librustc_infer/infer/higher_ranked/README.md @@ -1,8 +1,8 @@ To learn more about how Higher-ranked trait bounds work in the _old_ trait -solver, see [this chapter][oldhrtb] of the rustc-guide. +solver, see [this chapter][oldhrtb] of the rustc-dev-guide. To learn more about how they work in the _new_ trait solver, see [this chapter][newhrtb]. -[oldhrtb]: https://rust-lang.github.io/rustc-guide/traits/hrtb.html -[newhrtb]: https://rust-lang.github.io/rustc-guide/borrow_check/region_inference.html#placeholders-and-universes +[oldhrtb]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html +[newhrtb]: https://rustc-dev-guide.rust-lang.org/borrow_check/region_inference.html#placeholders-and-universes diff --git a/src/librustc_infer/infer/higher_ranked/mod.rs b/src/librustc_infer/infer/higher_ranked/mod.rs index 33781188a9550..105b987f85e96 100644 --- a/src/librustc_infer/infer/higher_ranked/mod.rs +++ b/src/librustc_infer/infer/higher_ranked/mod.rs @@ -71,9 +71,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// needed (but is also permitted). /// /// For more information about how placeholders and HRTBs work, see - /// the [rustc guide]. + /// the [rustc dev guide]. /// - /// [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/hrtb.html + /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html pub fn replace_bound_vars_with_placeholders<T>( &self, binder: &ty::Binder<T>, diff --git a/src/librustc_infer/infer/lexical_region_resolve/README.md b/src/librustc_infer/infer/lexical_region_resolve/README.md index c26b5625a90b6..e0b2c0bffeeb3 100644 --- a/src/librustc_infer/infer/lexical_region_resolve/README.md +++ b/src/librustc_infer/infer/lexical_region_resolve/README.md @@ -2,6 +2,6 @@ Lexical Region Resolution was removed in https://github.com/rust-lang/rust/pull/64790. Rust now uses Non-lexical lifetimes. For more info, please see the [borrowck -chapter][bc] in the rustc-guide. +chapter][bc] in the rustc-dev-guide. -[bc]: https://rust-lang.github.io/rustc-guide/borrow_check/region_inference.html +[bc]: https://rustc-dev-guide.rust-lang.org/borrow_check/region_inference.html diff --git a/src/librustc_infer/infer/region_constraints/README.md b/src/librustc_infer/infer/region_constraints/README.md index d789fb0de1093..0231dd0667725 100644 --- a/src/librustc_infer/infer/region_constraints/README.md +++ b/src/librustc_infer/infer/region_constraints/README.md @@ -1,3 +1,3 @@ -For info on how the current borrowck works, see the [rustc guide]. +For info on how the current borrowck works, see the [rustc dev guide]. -[rustc guide]: https://rust-lang.github.io/rustc-guide/borrow_check.html +[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html diff --git a/src/librustc_infer/lib.rs b/src/librustc_infer/lib.rs index 6c66ef47f33f0..49e99b574b892 100644 --- a/src/librustc_infer/lib.rs +++ b/src/librustc_infer/lib.rs @@ -5,9 +5,9 @@ //! this code handles low-level equality and subtyping operations. The //! type check pass in the compiler is found in the `librustc_typeck` crate. //! -//! For more information about how rustc works, see the [rustc guide]. +//! For more information about how rustc works, see the [rustc dev guide]. //! -//! [rustc guide]: https://rust-lang.github.io/rustc-guide/ +//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ //! //! # Note //! diff --git a/src/librustc_infer/traits/coherence.rs b/src/librustc_infer/traits/coherence.rs index 15c5f4d402ac3..9cf4ed8fe573a 100644 --- a/src/librustc_infer/traits/coherence.rs +++ b/src/librustc_infer/traits/coherence.rs @@ -1,8 +1,8 @@ -//! See Rustc Guide chapters on [trait-resolution] and [trait-specialization] for more info on how -//! this works. +//! See Rustc Dev Guide chapters on [trait-resolution] and [trait-specialization] for more info on +//! how this works. //! -//! [trait-resolution]: https://rust-lang.github.io/rustc-guide/traits/resolution.html -//! [trait-specialization]: https://rust-lang.github.io/rustc-guide/traits/specialization.html +//! [trait-resolution]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html +//! [trait-specialization]: https://rustc-dev-guide.rust-lang.org/traits/specialization.html use crate::infer::{CombinedSnapshot, InferOk, TyCtxtInferExt}; use crate::traits::select::IntercrateAmbiguityCause; diff --git a/src/librustc_infer/traits/mod.rs b/src/librustc_infer/traits/mod.rs index 800f8e91a7801..aa0cfedff9e8b 100644 --- a/src/librustc_infer/traits/mod.rs +++ b/src/librustc_infer/traits/mod.rs @@ -1,6 +1,6 @@ -//! Trait Resolution. See the [rustc guide] for more information on how this works. +//! Trait Resolution. See the [rustc dev guide] for more information on how this works. //! -//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html +//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html #[allow(dead_code)] pub mod auto_trait; diff --git a/src/librustc_infer/traits/query/type_op/mod.rs b/src/librustc_infer/traits/query/type_op/mod.rs index eb4c0a029e1b9..1644746c16eb1 100644 --- a/src/librustc_infer/traits/query/type_op/mod.rs +++ b/src/librustc_infer/traits/query/type_op/mod.rs @@ -44,7 +44,7 @@ pub trait TypeOp<'tcx>: Sized + fmt::Debug { /// first canonicalize the key and then invoke the query on the tcx, /// which produces the resulting query region constraints. /// -/// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html +/// [c]: https://rustc-dev-guide.rust-lang.org/traits/canonicalization.html pub trait QueryTypeOp<'tcx>: fmt::Debug + Sized + TypeFoldable<'tcx> + 'tcx { type QueryResponse: TypeFoldable<'tcx>; diff --git a/src/librustc_infer/traits/select.rs b/src/librustc_infer/traits/select.rs index c0d8f3cfd4f86..b50f14475fceb 100644 --- a/src/librustc_infer/traits/select.rs +++ b/src/librustc_infer/traits/select.rs @@ -1,8 +1,8 @@ // ignore-tidy-filelength -//! Candidate selection. See the [rustc guide] for more information on how this works. +//! Candidate selection. See the [rustc dev guide] for more information on how this works. //! -//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html#selection +//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html#selection use self::EvaluationResult::*; use self::SelectionCandidate::*; @@ -931,10 +931,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // // The selection process begins by examining all in-scope impls, // caller obligations, and so forth and assembling a list of - // candidates. See the [rustc guide] for more details. + // candidates. See the [rustc dev guide] for more details. // - // [rustc guide]: - // https://rust-lang.github.io/rustc-guide/traits/resolution.html#candidate-assembly + // [rustc dev guide]: + // https://rustc-dev-guide.rust-lang.org/traits/resolution.html#candidate-assembly fn candidate_from_obligation<'o>( &mut self, @@ -2447,10 +2447,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // // Confirmation unifies the output type parameters of the trait // with the values found in the obligation, possibly yielding a - // type error. See the [rustc guide] for more details. + // type error. See the [rustc dev guide] for more details. // - // [rustc guide]: - // https://rust-lang.github.io/rustc-guide/traits/resolution.html#confirmation + // [rustc dev guide]: + // https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation fn confirm_candidate( &mut self, diff --git a/src/librustc_infer/traits/specialize/mod.rs b/src/librustc_infer/traits/specialize/mod.rs index ee1c737c208f7..51da759da99f8 100644 --- a/src/librustc_infer/traits/specialize/mod.rs +++ b/src/librustc_infer/traits/specialize/mod.rs @@ -4,10 +4,10 @@ //! At the moment, this implementation support only the simple "chain" rule: //! If any two impls overlap, one must be a strict subset of the other. //! -//! See the [rustc guide] for a bit more detail on how specialization +//! See the [rustc dev guide] for a bit more detail on how specialization //! fits together with the rest of the trait machinery. //! -//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/specialization.html +//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/specialization.html pub mod specialization_graph; use specialization_graph::GraphExt; diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 1e5ed76c467b4..869eb1227f23b 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -103,6 +103,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.write_scalar(location.ptr, dest)?; } + sym::abort => { + M::abort(self)?; + } + sym::min_align_of | sym::pref_align_of | sym::needs_drop diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index 087517ff4e31d..366de6e55612a 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -169,6 +169,11 @@ pub trait Machine<'mir, 'tcx>: Sized { unwind: Option<mir::BasicBlock>, ) -> InterpResult<'tcx>; + /// Called to evaluate `Abort` MIR terminator. + fn abort(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx, !> { + throw_unsup_format!("aborting execution is not supported"); + } + /// Called for all binary operations where the LHS has pointer type. /// /// Returns a (value, overflowed) pair if the operation succeeded diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 22b1a7b7137d9..07c0f76e03a7e 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -356,7 +356,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { let base = match op.try_as_mplace(self) { Ok(mplace) => { - // The easy case + // We can reuse the mplace field computation logic for indirect operands. let field = self.mplace_field(mplace, field)?; return Ok(field.into()); } diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index a4815b9696ebb..856c654980ab7 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -410,14 +410,6 @@ where stride * field } layout::FieldPlacement::Union(count) => { - // This is a narrow bug-fix for rust-lang/rust#69191: if we are - // trying to access absent field of uninhabited variant, then - // signal UB (but don't ICE the compiler). - // FIXME temporary hack to work around incoherence between - // layout computation and MIR building - if field >= count as u64 && base.layout.abi == layout::Abi::Uninhabited { - throw_ub!(Unreachable); - } assert!( field < count as u64, "Tried to access field {} of union {:#?} with {} fields", diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index b5c34daf8a318..473ed9d13ecfb 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -99,6 +99,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } + Abort => { + M::abort(self)?; + } + // When we encounter Resume, we've finished unwinding // cleanup for the current stack frame. We pop it in order // to continue unwinding the next frame @@ -114,15 +118,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Unreachable => throw_ub!(Unreachable), // These should never occur for MIR we actually run. - DropAndReplace { .. } | FalseEdges { .. } | FalseUnwind { .. } => { + DropAndReplace { .. } + | FalseEdges { .. } + | FalseUnwind { .. } + | Yield { .. } + | GeneratorDrop => { bug!("{:#?} should have been eliminated by MIR pass", terminator.kind) } - - // These are not (yet) supported. It is unclear if they even can occur in - // MIR that we actually run. - Yield { .. } | GeneratorDrop | Abort => { - throw_unsup_format!("Unsupported terminator kind: {:#?}", terminator.kind) - } } Ok(()) diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs index fe75062ee503c..f085e215aa7a9 100644 --- a/src/librustc_parse/lib.rs +++ b/src/librustc_parse/lib.rs @@ -13,7 +13,7 @@ use rustc_errors::{Diagnostic, FatalError, Level, PResult}; use rustc_session::parse::ParseSess; use rustc_span::{FileName, SourceFile, Span}; -use std::path::{Path, PathBuf}; +use std::path::Path; use std::str; use log::info; @@ -25,24 +25,6 @@ pub mod parser; use parser::{emit_unclosed_delims, make_unclosed_delims_error, Parser}; pub mod lexer; pub mod validate_attr; -#[macro_use] -pub mod config; - -#[derive(Clone)] -pub struct Directory { - pub path: PathBuf, - pub ownership: DirectoryOwnership, -} - -#[derive(Copy, Clone)] -pub enum DirectoryOwnership { - Owned { - // None if `mod.rs`, `Some("foo")` if we're in `foo.rs`. - relative: Option<ast::Ident>, - }, - UnownedViaBlock, - UnownedViaMod, -} // A bunch of utility functions of the form `parse_<thing>_from_<source>` // where <thing> includes crate, expr, item, stmt, tts, and one that @@ -119,10 +101,7 @@ pub fn maybe_new_parser_from_source_str( name: FileName, source: String, ) -> Result<Parser<'_>, Vec<Diagnostic>> { - let mut parser = - maybe_source_file_to_parser(sess, sess.source_map().new_source_file(name, source))?; - parser.recurse_into_file_modules = false; - Ok(parser) + maybe_source_file_to_parser(sess, sess.source_map().new_source_file(name, source)) } /// Creates a new parser, handling errors as appropriate if the file doesn't exist. @@ -146,12 +125,10 @@ pub fn maybe_new_parser_from_file<'a>( pub fn new_sub_parser_from_file<'a>( sess: &'a ParseSess, path: &Path, - directory_ownership: DirectoryOwnership, module_name: Option<String>, sp: Span, ) -> Parser<'a> { let mut p = source_file_to_parser(sess, file_to_source_file(sess, path, Some(sp))); - p.directory.ownership = directory_ownership; p.root_module_name = module_name; p } @@ -257,26 +234,7 @@ pub fn stream_to_parser<'a>( stream: TokenStream, subparser_name: Option<&'static str>, ) -> Parser<'a> { - Parser::new(sess, stream, None, true, false, subparser_name) -} - -/// Given a stream, the `ParseSess` and the base directory, produces a parser. -/// -/// Use this function when you are creating a parser from the token stream -/// and also care about the current working directory of the parser (e.g., -/// you are trying to resolve modules defined inside a macro invocation). -/// -/// # Note -/// -/// The main usage of this function is outside of rustc, for those who uses -/// librustc_ast as a library. Please do not remove this function while refactoring -/// just because it is not used in rustc codebase! -pub fn stream_to_parser_with_base_dir<'a>( - sess: &'a ParseSess, - stream: TokenStream, - base_dir: Directory, -) -> Parser<'a> { - Parser::new(sess, stream, Some(base_dir), true, false, None) + Parser::new(sess, stream, false, subparser_name) } /// Runs the given subparser `f` on the tokens of the given `attr`'s item. @@ -286,7 +244,7 @@ pub fn parse_in<'a, T>( name: &'static str, mut f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, ) -> PResult<'a, T> { - let mut parser = Parser::new(sess, tts, None, false, false, Some(name)); + let mut parser = Parser::new(sess, tts, false, Some(name)); let result = f(&mut parser)?; if parser.token != token::Eof { parser.unexpected()?; diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 7c1df531ad16e..87255386b9e66 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -40,55 +40,12 @@ pub(super) fn dummy_arg(ident: Ident) -> Param { } pub enum Error { - FileNotFoundForModule { - mod_name: String, - default_path: String, - secondary_path: String, - dir_path: String, - }, - DuplicatePaths { - mod_name: String, - default_path: String, - secondary_path: String, - }, UselessDocComment, } impl Error { fn span_err(self, sp: impl Into<MultiSpan>, handler: &Handler) -> DiagnosticBuilder<'_> { match self { - Error::FileNotFoundForModule { - ref mod_name, - ref default_path, - ref secondary_path, - ref dir_path, - } => { - let mut err = struct_span_err!( - handler, - sp, - E0583, - "file not found for module `{}`", - mod_name, - ); - err.help(&format!( - "name the file either {} or {} inside the directory \"{}\"", - default_path, secondary_path, dir_path, - )); - err - } - Error::DuplicatePaths { ref mod_name, ref default_path, ref secondary_path } => { - let mut err = struct_span_err!( - handler, - sp, - E0584, - "file for module `{}` found at both {} and {}", - mod_name, - default_path, - secondary_path, - ); - err.help("delete or rename one of them to remove the ambiguity"); - err - } Error::UselessDocComment => { let mut err = struct_span_err!( handler, diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 3932bbd7564c3..04ba08bcb18bd 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -5,7 +5,7 @@ use super::{FollowedByType, Parser, PathStyle}; use crate::maybe_whole; use rustc_ast::ast::{self, AttrStyle, AttrVec, Attribute, Ident, DUMMY_NODE_ID}; -use rustc_ast::ast::{AssocItem, AssocItemKind, ForeignItemKind, Item, ItemKind}; +use rustc_ast::ast::{AssocItem, AssocItemKind, ForeignItemKind, Item, ItemKind, Mod}; use rustc_ast::ast::{ Async, Const, Defaultness, IsAuto, PathSegment, Unsafe, UseTree, UseTreeKind, }; @@ -15,7 +15,7 @@ use rustc_ast::ast::{ use rustc_ast::ast::{EnumDef, Generics, StructField, TraitRef, Ty, TyKind, Variant, VariantData}; use rustc_ast::ast::{FnHeader, ForeignItem, Mutability, Visibility, VisibilityKind}; use rustc_ast::ptr::P; -use rustc_ast::token; +use rustc_ast::token::{self, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability, PResult, StashKey}; @@ -27,6 +27,61 @@ use log::debug; use std::convert::TryFrom; use std::mem; +impl<'a> Parser<'a> { + /// Parses a source module as a crate. This is the main entry point for the parser. + pub fn parse_crate_mod(&mut self) -> PResult<'a, ast::Crate> { + let lo = self.token.span; + let (module, attrs) = self.parse_mod(&token::Eof)?; + let span = lo.to(self.token.span); + let proc_macros = Vec::new(); // Filled in by `proc_macro_harness::inject()`. + Ok(ast::Crate { attrs, module, span, proc_macros }) + } + + /// Parses a `mod <foo> { ... }` or `mod <foo>;` item. + fn parse_item_mod(&mut self, attrs: &mut Vec<Attribute>) -> PResult<'a, ItemInfo> { + let id = self.parse_ident()?; + let (module, mut inner_attrs) = if self.eat(&token::Semi) { + Default::default() + } else { + self.expect(&token::OpenDelim(token::Brace))?; + self.parse_mod(&token::CloseDelim(token::Brace))? + }; + attrs.append(&mut inner_attrs); + Ok((id, ItemKind::Mod(module))) + } + + /// Parses the contents of a module (inner attributes followed by module items). + pub fn parse_mod(&mut self, term: &TokenKind) -> PResult<'a, (Mod, Vec<Attribute>)> { + let lo = self.token.span; + let attrs = self.parse_inner_attributes()?; + let module = self.parse_mod_items(term, lo)?; + Ok((module, attrs)) + } + + /// Given a termination token, parses all of the items in a module. + fn parse_mod_items(&mut self, term: &TokenKind, inner_lo: Span) -> PResult<'a, Mod> { + let mut items = vec![]; + while let Some(item) = self.parse_item()? { + items.push(item); + self.maybe_consume_incorrect_semicolon(&items); + } + + if !self.eat(term) { + let token_str = super::token_descr(&self.token); + if !self.maybe_consume_incorrect_semicolon(&items) { + let msg = &format!("expected item, found {}", token_str); + let mut err = self.struct_span_err(self.token.span, msg); + err.span_label(self.token.span, "expected item"); + return Err(err); + } + } + + let hi = if self.token.span.is_dummy() { inner_lo } else { self.prev_token.span }; + + Ok(Mod { inner: inner_lo.to(hi), items, inline: true }) + } +} + pub(super) type ItemInfo = (Ident, ItemKind); impl<'a> Parser<'a> { diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 9376c7c1c724d..bb6793d08aa27 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -1,8 +1,6 @@ pub mod attr; mod expr; mod item; -mod module; -pub use module::{ModulePath, ModulePathSuccess}; mod pat; mod path; mod ty; @@ -13,7 +11,6 @@ mod stmt; use diagnostics::Error; use crate::lexer::UnmatchedBrace; -use crate::{Directory, DirectoryOwnership}; use log::debug; use rustc_ast::ast::DUMMY_NODE_ID; @@ -28,11 +25,9 @@ use rustc_ast::util::comments::{doc_comment_style, strip_doc_comment_decoration} use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, FatalError, PResult}; use rustc_session::parse::ParseSess; -use rustc_span::source_map::respan; +use rustc_span::source_map::{respan, Span, DUMMY_SP}; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_span::{FileName, Span, DUMMY_SP}; -use std::path::PathBuf; use std::{cmp, mem, slice}; bitflags::bitflags! { @@ -93,11 +88,6 @@ pub struct Parser<'a> { /// The previous token. pub prev_token: Token, restrictions: Restrictions, - /// Used to determine the path to externally loaded source files. - pub(super) directory: Directory, - /// `true` to parse sub-modules in other files. - // Public for rustfmt usage. - pub recurse_into_file_modules: bool, /// Name of the root module this parser originated from. If `None`, then the /// name is not known. This does not change while the parser is descending /// into modules, and sub-parsers have new values for this name. @@ -105,9 +95,6 @@ pub struct Parser<'a> { expected_tokens: Vec<TokenType>, token_cursor: TokenCursor, desugar_doc_comments: bool, - /// `true` we should configure out of line modules as we parse. - // Public for rustfmt usage. - pub cfg_mods: bool, /// This field is used to keep track of how many left angle brackets we have seen. This is /// required in order to detect extra leading left angle brackets (`<` characters) and error /// appropriately. @@ -355,8 +342,6 @@ impl<'a> Parser<'a> { pub fn new( sess: &'a ParseSess, tokens: TokenStream, - directory: Option<Directory>, - recurse_into_file_modules: bool, desugar_doc_comments: bool, subparser_name: Option<&'static str>, ) -> Self { @@ -365,11 +350,6 @@ impl<'a> Parser<'a> { token: Token::dummy(), prev_token: Token::dummy(), restrictions: Restrictions::empty(), - recurse_into_file_modules, - directory: Directory { - path: PathBuf::new(), - ownership: DirectoryOwnership::Owned { relative: None }, - }, root_module_name: None, expected_tokens: Vec::new(), token_cursor: TokenCursor { @@ -377,7 +357,6 @@ impl<'a> Parser<'a> { stack: Vec::new(), }, desugar_doc_comments, - cfg_mods: true, unmatched_angle_bracket_count: 0, max_angle_bracket_count: 0, unclosed_delims: Vec::new(), @@ -389,18 +368,6 @@ impl<'a> Parser<'a> { // Make parser point to the first token. parser.bump(); - if let Some(directory) = directory { - parser.directory = directory; - } else if !parser.token.span.is_dummy() { - if let Some(FileName::Real(path)) = - &sess.source_map().lookup_char_pos(parser.token.span.lo()).file.unmapped_path - { - if let Some(directory_path) = path.parent() { - parser.directory.path = directory_path.to_path_buf(); - } - } - } - parser } diff --git a/src/librustc_parse/parser/module.rs b/src/librustc_parse/parser/module.rs deleted file mode 100644 index b436f1969bb48..0000000000000 --- a/src/librustc_parse/parser/module.rs +++ /dev/null @@ -1,306 +0,0 @@ -use super::diagnostics::Error; -use super::item::ItemInfo; -use super::Parser; - -use crate::{new_sub_parser_from_file, DirectoryOwnership}; - -use rustc_ast::ast::{self, Attribute, Crate, Ident, ItemKind, Mod}; -use rustc_ast::attr; -use rustc_ast::token::{self, TokenKind}; -use rustc_errors::PResult; -use rustc_span::source_map::{FileName, SourceMap, Span, DUMMY_SP}; -use rustc_span::symbol::sym; - -use std::path::{self, Path, PathBuf}; - -/// Information about the path to a module. -// Public for rustfmt usage. -pub struct ModulePath { - name: String, - path_exists: bool, - pub result: Result<ModulePathSuccess, Error>, -} - -// Public for rustfmt usage. -pub struct ModulePathSuccess { - pub path: PathBuf, - pub directory_ownership: DirectoryOwnership, -} - -impl<'a> Parser<'a> { - /// Parses a source module as a crate. This is the main entry point for the parser. - pub fn parse_crate_mod(&mut self) -> PResult<'a, Crate> { - let lo = self.token.span; - let krate = Ok(ast::Crate { - attrs: self.parse_inner_attributes()?, - module: self.parse_mod_items(&token::Eof, lo)?, - span: lo.to(self.token.span), - // Filled in by proc_macro_harness::inject() - proc_macros: Vec::new(), - }); - krate - } - - /// Parses a `mod <foo> { ... }` or `mod <foo>;` item. - pub(super) fn parse_item_mod(&mut self, attrs: &mut Vec<Attribute>) -> PResult<'a, ItemInfo> { - let in_cfg = crate::config::process_configure_mod(self.sess, self.cfg_mods, attrs); - - let id_span = self.token.span; - let id = self.parse_ident()?; - let (module, mut inner_attrs) = if self.eat(&token::Semi) { - if in_cfg && self.recurse_into_file_modules { - // This mod is in an external file. Let's go get it! - let ModulePathSuccess { path, directory_ownership } = - self.submod_path(id, &attrs, id_span)?; - self.eval_src_mod(path, directory_ownership, id.to_string(), id_span)? - } else { - (ast::Mod { inner: DUMMY_SP, items: Vec::new(), inline: false }, Vec::new()) - } - } else { - let old_directory = self.directory.clone(); - self.push_directory(id, &attrs); - - self.expect(&token::OpenDelim(token::Brace))?; - let mod_inner_lo = self.token.span; - let inner_attrs = self.parse_inner_attributes()?; - let module = self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)?; - - self.directory = old_directory; - (module, inner_attrs) - }; - attrs.append(&mut inner_attrs); - Ok((id, ItemKind::Mod(module))) - } - - /// Given a termination token, parses all of the items in a module. - fn parse_mod_items(&mut self, term: &TokenKind, inner_lo: Span) -> PResult<'a, Mod> { - let mut items = vec![]; - while let Some(item) = self.parse_item()? { - items.push(item); - self.maybe_consume_incorrect_semicolon(&items); - } - - if !self.eat(term) { - let token_str = super::token_descr(&self.token); - if !self.maybe_consume_incorrect_semicolon(&items) { - let msg = &format!("expected item, found {}", token_str); - let mut err = self.struct_span_err(self.token.span, msg); - err.span_label(self.token.span, "expected item"); - return Err(err); - } - } - - let hi = if self.token.span.is_dummy() { inner_lo } else { self.prev_token.span }; - - Ok(Mod { inner: inner_lo.to(hi), items, inline: true }) - } - - fn submod_path( - &mut self, - id: ast::Ident, - outer_attrs: &[Attribute], - id_sp: Span, - ) -> PResult<'a, ModulePathSuccess> { - if let Some(path) = Parser::submod_path_from_attr(outer_attrs, &self.directory.path) { - return Ok(ModulePathSuccess { - directory_ownership: match path.file_name().and_then(|s| s.to_str()) { - // All `#[path]` files are treated as though they are a `mod.rs` file. - // This means that `mod foo;` declarations inside `#[path]`-included - // files are siblings, - // - // Note that this will produce weirdness when a file named `foo.rs` is - // `#[path]` included and contains a `mod foo;` declaration. - // If you encounter this, it's your own darn fault :P - Some(_) => DirectoryOwnership::Owned { relative: None }, - _ => DirectoryOwnership::UnownedViaMod, - }, - path, - }); - } - - let relative = match self.directory.ownership { - DirectoryOwnership::Owned { relative } => relative, - DirectoryOwnership::UnownedViaBlock | DirectoryOwnership::UnownedViaMod => None, - }; - let paths = - Parser::default_submod_path(id, relative, &self.directory.path, self.sess.source_map()); - - match self.directory.ownership { - DirectoryOwnership::Owned { .. } => { - paths.result.map_err(|err| self.span_fatal_err(id_sp, err)) - } - DirectoryOwnership::UnownedViaBlock => { - let msg = "Cannot declare a non-inline module inside a block \ - unless it has a path attribute"; - let mut err = self.struct_span_err(id_sp, msg); - if paths.path_exists { - let msg = format!( - "Maybe `use` the module `{}` instead of redeclaring it", - paths.name - ); - err.span_note(id_sp, &msg); - } - Err(err) - } - DirectoryOwnership::UnownedViaMod => { - let mut err = - self.struct_span_err(id_sp, "cannot declare a new module at this location"); - if !id_sp.is_dummy() { - let src_path = self.sess.source_map().span_to_filename(id_sp); - if let FileName::Real(src_path) = src_path { - if let Some(stem) = src_path.file_stem() { - let mut dest_path = src_path.clone(); - dest_path.set_file_name(stem); - dest_path.push("mod.rs"); - err.span_note( - id_sp, - &format!( - "maybe move this module `{}` to its own \ - directory via `{}`", - src_path.display(), - dest_path.display() - ), - ); - } - } - } - if paths.path_exists { - err.span_note( - id_sp, - &format!( - "... or maybe `use` the module `{}` instead \ - of possibly redeclaring it", - paths.name - ), - ); - } - Err(err) - } - } - } - - // Public for rustfmt usage. - pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option<PathBuf> { - if let Some(s) = attr::first_attr_value_str_by_name(attrs, sym::path) { - let s = s.as_str(); - - // On windows, the base path might have the form - // `\\?\foo\bar` in which case it does not tolerate - // mixed `/` and `\` separators, so canonicalize - // `/` to `\`. - #[cfg(windows)] - let s = s.replace("/", "\\"); - Some(dir_path.join(&*s)) - } else { - None - } - } - - /// Returns a path to a module. - // Public for rustfmt usage. - pub fn default_submod_path( - id: ast::Ident, - relative: Option<ast::Ident>, - dir_path: &Path, - source_map: &SourceMap, - ) -> ModulePath { - // If we're in a foo.rs file instead of a mod.rs file, - // we need to look for submodules in - // `./foo/<id>.rs` and `./foo/<id>/mod.rs` rather than - // `./<id>.rs` and `./<id>/mod.rs`. - let relative_prefix_string; - let relative_prefix = if let Some(ident) = relative { - relative_prefix_string = format!("{}{}", ident.name, path::MAIN_SEPARATOR); - &relative_prefix_string - } else { - "" - }; - - let mod_name = id.name.to_string(); - let default_path_str = format!("{}{}.rs", relative_prefix, mod_name); - let secondary_path_str = - format!("{}{}{}mod.rs", relative_prefix, mod_name, path::MAIN_SEPARATOR); - let default_path = dir_path.join(&default_path_str); - let secondary_path = dir_path.join(&secondary_path_str); - let default_exists = source_map.file_exists(&default_path); - let secondary_exists = source_map.file_exists(&secondary_path); - - let result = match (default_exists, secondary_exists) { - (true, false) => Ok(ModulePathSuccess { - path: default_path, - directory_ownership: DirectoryOwnership::Owned { relative: Some(id) }, - }), - (false, true) => Ok(ModulePathSuccess { - path: secondary_path, - directory_ownership: DirectoryOwnership::Owned { relative: None }, - }), - (false, false) => Err(Error::FileNotFoundForModule { - mod_name: mod_name.clone(), - default_path: default_path_str, - secondary_path: secondary_path_str, - dir_path: dir_path.display().to_string(), - }), - (true, true) => Err(Error::DuplicatePaths { - mod_name: mod_name.clone(), - default_path: default_path_str, - secondary_path: secondary_path_str, - }), - }; - - ModulePath { name: mod_name, path_exists: default_exists || secondary_exists, result } - } - - /// Reads a module from a source file. - fn eval_src_mod( - &mut self, - path: PathBuf, - directory_ownership: DirectoryOwnership, - name: String, - id_sp: Span, - ) -> PResult<'a, (Mod, Vec<Attribute>)> { - let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut(); - if let Some(i) = included_mod_stack.iter().position(|p| *p == path) { - let mut err = String::from("circular modules: "); - let len = included_mod_stack.len(); - for p in &included_mod_stack[i..len] { - err.push_str(&p.to_string_lossy()); - err.push_str(" -> "); - } - err.push_str(&path.to_string_lossy()); - return Err(self.struct_span_err(id_sp, &err[..])); - } - included_mod_stack.push(path.clone()); - drop(included_mod_stack); - - let mut p0 = - new_sub_parser_from_file(self.sess, &path, directory_ownership, Some(name), id_sp); - p0.cfg_mods = self.cfg_mods; - let mod_inner_lo = p0.token.span; - let mod_attrs = p0.parse_inner_attributes()?; - let mut m0 = p0.parse_mod_items(&token::Eof, mod_inner_lo)?; - m0.inline = false; - self.sess.included_mod_stack.borrow_mut().pop(); - Ok((m0, mod_attrs)) - } - - fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) { - if let Some(path) = attr::first_attr_value_str_by_name(attrs, sym::path) { - self.directory.path.push(&*path.as_str()); - self.directory.ownership = DirectoryOwnership::Owned { relative: None }; - } else { - // We have to push on the current module name in the case of relative - // paths in order to ensure that any additional module paths from inline - // `mod x { ... }` come after the relative extension. - // - // For example, a `mod z { ... }` inside `x/y.rs` should set the current - // directory path to `/x/y/z`, not `/x/z` with a relative offset of `y`. - if let DirectoryOwnership::Owned { relative } = &mut self.directory.ownership { - if let Some(ident) = relative.take() { - // remove the relative offset - self.directory.path.push(&*ident.as_str()); - } - } - self.directory.path.push(&*id.as_str()); - } - } -} diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index 489549a57505f..ac87335d5decf 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/src/librustc_parse/parser/stmt.rs @@ -5,7 +5,6 @@ use super::pat::GateOr; use super::path::PathStyle; use super::{BlockMode, Parser, Restrictions, SemiColonMode}; use crate::maybe_whole; -use crate::DirectoryOwnership; use rustc_ast::ast; use rustc_ast::ast::{AttrStyle, AttrVec, Attribute, Mac, MacStmtStyle}; @@ -54,7 +53,7 @@ impl<'a> Parser<'a> { // that starts like a path (1 token), but it fact not a path. // Also, we avoid stealing syntax from `parse_item_`. self.parse_stmt_path_start(lo, attrs)? - } else if let Some(item) = self.parse_stmt_item(attrs.clone())? { + } else if let Some(item) = self.parse_item_common(attrs.clone(), false, true, |_| true)? { // FIXME: Bad copy of attrs self.mk_stmt(lo.to(item.span), StmtKind::Item(P(item))) } else if self.eat(&token::Semi) { @@ -72,13 +71,6 @@ impl<'a> Parser<'a> { Ok(Some(stmt)) } - fn parse_stmt_item(&mut self, attrs: Vec<Attribute>) -> PResult<'a, Option<ast::Item>> { - let old = mem::replace(&mut self.directory.ownership, DirectoryOwnership::UnownedViaBlock); - let item = self.parse_item_common(attrs, false, true, |_| true)?; - self.directory.ownership = old; - Ok(item) - } - fn parse_stmt_path_start(&mut self, lo: Span, attrs: Vec<Attribute>) -> PResult<'a, Stmt> { let path = self.parse_path(PathStyle::Expr)?; diff --git a/src/librustc_parse/validate_attr.rs b/src/librustc_parse/validate_attr.rs index 029aa5ed2baea..2512878ec65be 100644 --- a/src/librustc_parse/validate_attr.rs +++ b/src/librustc_parse/validate_attr.rs @@ -57,7 +57,7 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta }) } -crate fn check_meta_bad_delim(sess: &ParseSess, span: DelimSpan, delim: MacDelimiter, msg: &str) { +pub fn check_meta_bad_delim(sess: &ParseSess, span: DelimSpan, delim: MacDelimiter, msg: &str) { if let ast::MacDelimiter::Parenthesis = delim { return; } diff --git a/src/librustc_passes/region.rs b/src/librustc_passes/region.rs index 282bd20a9bed9..908785faff073 100644 --- a/src/librustc_passes/region.rs +++ b/src/librustc_passes/region.rs @@ -2,9 +2,9 @@ //! the parent links in the region hierarchy. //! //! For more information about how MIR-based region-checking works, -//! see the [rustc guide]. +//! see the [rustc dev guide]. //! -//! [rustc guide]: https://rust-lang.github.io/rustc-guide/borrow_check.html +//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html use rustc::hir::map::Map; use rustc::middle::region::*; diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index d8ce9bbdfb30b..6cb7cbf14fdd7 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -120,6 +120,7 @@ symbols! { abi_unadjusted, abi_vectorcall, abi_x86_interrupt, + abort, aborts, address, add_with_overflow, diff --git a/src/librustc_target/README.md b/src/librustc_target/README.md index a22000ea9d280..ac1e03385d181 100644 --- a/src/librustc_target/README.md +++ b/src/librustc_target/README.md @@ -1,6 +1,6 @@ `librustc_target` contains some very low-level details that are specific to different compilation targets and so forth. -For more information about how rustc works, see the [rustc guide]. +For more information about how rustc works, see the [rustc dev guide]. -[rustc guide]: https://rust-lang.github.io/rustc-guide/ +[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 2f8bbd66c322b..afa30e7e632a7 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -660,7 +660,10 @@ impl FieldPlacement { pub fn offset(&self, i: usize) -> Size { match *self { - FieldPlacement::Union(_) => Size::ZERO, + FieldPlacement::Union(count) => { + assert!(i < count, "tried to access field {} of union with {} fields", i, count); + Size::ZERO + } FieldPlacement::Array { stride, count } => { let i = i as u64; assert!(i < count); diff --git a/src/librustc_target/spec/aarch64_apple_ios.rs b/src/librustc_target/spec/aarch64_apple_ios.rs index 6549be41ea944..e896b46da9a62 100644 --- a/src/librustc_target/spec/aarch64_apple_ios.rs +++ b/src/librustc_target/spec/aarch64_apple_ios.rs @@ -1,8 +1,8 @@ -use super::apple_ios_base::{opts, Arch}; +use super::apple_sdk_base::{opts, AppleOS, Arch}; use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { - let base = opts(Arch::Arm64)?; + let base = opts(Arch::Arm64, AppleOS::iOS)?; Ok(Target { llvm_target: "arm64-apple-ios".to_string(), target_endian: "little".to_string(), diff --git a/src/librustc_target/spec/aarch64_apple_tvos.rs b/src/librustc_target/spec/aarch64_apple_tvos.rs new file mode 100644 index 0000000000000..794bc7900e747 --- /dev/null +++ b/src/librustc_target/spec/aarch64_apple_tvos.rs @@ -0,0 +1,25 @@ +use super::apple_sdk_base::{opts, AppleOS, Arch}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + let base = opts(Arch::Arm64, AppleOS::tvOS)?; + Ok(Target { + llvm_target: "arm64-apple-tvos".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".to_string(), + arch: "aarch64".to_string(), + target_os: "tvos".to_string(), + target_env: String::new(), + target_vendor: "apple".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: TargetOptions { + features: "+neon,+fp-armv8,+cyclone".to_string(), + eliminate_frame_pointer: false, + max_atomic_width: Some(128), + abi_blacklist: super::arm_base::abi_blacklist(), + ..base + }, + }) +} diff --git a/src/librustc_target/spec/apple_ios_base.rs b/src/librustc_target/spec/apple_sdk_base.rs similarity index 77% rename from src/librustc_target/spec/apple_ios_base.rs rename to src/librustc_target/spec/apple_sdk_base.rs index 2673748321d79..513754352fbfb 100644 --- a/src/librustc_target/spec/apple_ios_base.rs +++ b/src/librustc_target/spec/apple_sdk_base.rs @@ -5,7 +5,6 @@ use std::path::Path; use std::process::Command; use Arch::*; - #[allow(non_camel_case_types)] #[derive(Copy, Clone)] pub enum Arch { @@ -17,6 +16,13 @@ pub enum Arch { X86_64_macabi, } +#[allow(non_camel_case_types)] +#[derive(Copy, Clone)] +pub enum AppleOS { + tvOS, + iOS, +} + impl Arch { pub fn to_string(self) -> &'static str { match self { @@ -41,6 +47,17 @@ pub fn get_sdk_root(sdk_name: &str) -> Result<String, String> { let p = Path::new(&sdkroot); match sdk_name { // Ignore `SDKROOT` if it's clearly set for the wrong platform. + "appletvos" + if sdkroot.contains("TVSimulator.platform") + || sdkroot.contains("MacOSX.platform") => + { + () + } + "appletvsimulator" + if sdkroot.contains("TVOS.platform") || sdkroot.contains("MacOSX.platform") => + { + () + } "iphoneos" if sdkroot.contains("iPhoneSimulator.platform") || sdkroot.contains("MacOSX.platform") => @@ -82,11 +99,17 @@ pub fn get_sdk_root(sdk_name: &str) -> Result<String, String> { } } -fn build_pre_link_args(arch: Arch) -> Result<LinkArgs, String> { - let sdk_name = match arch { - Armv7 | Armv7s | Arm64 => "iphoneos", - I386 | X86_64 => "iphonesimulator", - X86_64_macabi => "macosx10.15", +fn build_pre_link_args(arch: Arch, os: AppleOS) -> Result<LinkArgs, String> { + let sdk_name = match (arch, os) { + (Arm64, AppleOS::tvOS) => "appletvos", + (X86_64, AppleOS::tvOS) => "appletvsimulator", + (Armv7, AppleOS::iOS) => "iphoneos", + (Armv7s, AppleOS::iOS) => "iphoneos", + (Arm64, AppleOS::iOS) => "iphoneos", + (I386, AppleOS::iOS) => "iphonesimulator", + (X86_64, AppleOS::iOS) => "iphonesimulator", + (X86_64_macabi, AppleOS::iOS) => "macosx10.15", + _ => unreachable!(), }; let arch_name = arch.to_string(); @@ -128,8 +151,8 @@ fn link_env_remove(arch: Arch) -> Vec<String> { } } -pub fn opts(arch: Arch) -> Result<TargetOptions, String> { - let pre_link_args = build_pre_link_args(arch)?; +pub fn opts(arch: Arch, os: AppleOS) -> Result<TargetOptions, String> { + let pre_link_args = build_pre_link_args(arch, os)?; Ok(TargetOptions { cpu: target_cpu(arch), dynamic_linking: false, diff --git a/src/librustc_target/spec/armv7_apple_ios.rs b/src/librustc_target/spec/armv7_apple_ios.rs index aa2d32e2d7935..c0c2ae909f8f0 100644 --- a/src/librustc_target/spec/armv7_apple_ios.rs +++ b/src/librustc_target/spec/armv7_apple_ios.rs @@ -1,8 +1,8 @@ -use super::apple_ios_base::{opts, Arch}; +use super::apple_sdk_base::{opts, AppleOS, Arch}; use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { - let base = opts(Arch::Armv7)?; + let base = opts(Arch::Armv7, AppleOS::iOS)?; Ok(Target { llvm_target: "armv7-apple-ios".to_string(), target_endian: "little".to_string(), diff --git a/src/librustc_target/spec/armv7s_apple_ios.rs b/src/librustc_target/spec/armv7s_apple_ios.rs index 6514643a64dae..6a5654f10d416 100644 --- a/src/librustc_target/spec/armv7s_apple_ios.rs +++ b/src/librustc_target/spec/armv7s_apple_ios.rs @@ -1,8 +1,8 @@ -use super::apple_ios_base::{opts, Arch}; +use super::apple_sdk_base::{opts, AppleOS, Arch}; use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { - let base = opts(Arch::Armv7s)?; + let base = opts(Arch::Armv7s, AppleOS::iOS)?; Ok(Target { llvm_target: "armv7s-apple-ios".to_string(), target_endian: "little".to_string(), diff --git a/src/librustc_target/spec/i386_apple_ios.rs b/src/librustc_target/spec/i386_apple_ios.rs index a6c1d24fa62a1..a121d49769d61 100644 --- a/src/librustc_target/spec/i386_apple_ios.rs +++ b/src/librustc_target/spec/i386_apple_ios.rs @@ -1,8 +1,8 @@ -use super::apple_ios_base::{opts, Arch}; +use super::apple_sdk_base::{opts, AppleOS, Arch}; use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { - let base = opts(Arch::I386)?; + let base = opts(Arch::I386, AppleOS::iOS)?; Ok(Target { llvm_target: "i386-apple-ios".to_string(), target_endian: "little".to_string(), diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 67f45d3d230ef..37eabb4f26d4b 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -47,7 +47,7 @@ use rustc_macros::HashStable_Generic; pub mod abi; mod android_base; mod apple_base; -mod apple_ios_base; +mod apple_sdk_base; mod arm_base; mod cloudabi_base; mod dragonfly_base; @@ -434,6 +434,8 @@ supported_targets! { ("armv7-apple-ios", armv7_apple_ios), ("armv7s-apple-ios", armv7s_apple_ios), ("x86_64-apple-ios-macabi", x86_64_apple_ios_macabi), + ("aarch64-apple-tvos", aarch64_apple_tvos), + ("x86_64-apple-tvos", x86_64_apple_tvos), ("armebv7r-none-eabi", armebv7r_none_eabi), ("armebv7r-none-eabihf", armebv7r_none_eabihf), diff --git a/src/librustc_target/spec/x86_64_apple_ios.rs b/src/librustc_target/spec/x86_64_apple_ios.rs index ca02e2deabcf2..cfcf856836b14 100644 --- a/src/librustc_target/spec/x86_64_apple_ios.rs +++ b/src/librustc_target/spec/x86_64_apple_ios.rs @@ -1,8 +1,8 @@ -use super::apple_ios_base::{opts, Arch}; +use super::apple_sdk_base::{opts, AppleOS, Arch}; use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { - let base = opts(Arch::X86_64)?; + let base = opts(Arch::X86_64, AppleOS::iOS)?; Ok(Target { llvm_target: "x86_64-apple-ios".to_string(), target_endian: "little".to_string(), diff --git a/src/librustc_target/spec/x86_64_apple_ios_macabi.rs b/src/librustc_target/spec/x86_64_apple_ios_macabi.rs index 5f4f6ade682d8..c42d09117259d 100644 --- a/src/librustc_target/spec/x86_64_apple_ios_macabi.rs +++ b/src/librustc_target/spec/x86_64_apple_ios_macabi.rs @@ -1,8 +1,8 @@ -use super::apple_ios_base::{opts, Arch}; +use super::apple_sdk_base::{opts, AppleOS, Arch}; use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { - let base = opts(Arch::X86_64_macabi)?; + let base = opts(Arch::X86_64_macabi, AppleOS::iOS)?; Ok(Target { llvm_target: "x86_64-apple-ios13.0-macabi".to_string(), target_endian: "little".to_string(), diff --git a/src/librustc_target/spec/x86_64_apple_tvos.rs b/src/librustc_target/spec/x86_64_apple_tvos.rs new file mode 100644 index 0000000000000..a56062c0b2b5d --- /dev/null +++ b/src/librustc_target/spec/x86_64_apple_tvos.rs @@ -0,0 +1,19 @@ +use super::apple_sdk_base::{opts, AppleOS, Arch}; +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + let base = opts(Arch::X86_64, AppleOS::iOS)?; + Ok(Target { + llvm_target: "x86_64-apple-tvos".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:o-i64:64-f80:128-n8:16:32:64-S128".to_string(), + arch: "x86_64".to_string(), + target_os: "tvos".to_string(), + target_env: String::new(), + target_vendor: "apple".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: TargetOptions { max_atomic_width: Some(64), stack_probes: true, ..base }, + }) +} diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs index 97b81c224d593..9b48cf489ba26 100644 --- a/src/librustc_traits/lowering/mod.rs +++ b/src/librustc_traits/lowering/mod.rs @@ -108,13 +108,13 @@ impl<'tcx> Lower<PolyDomainGoal<'tcx>> for ty::Predicate<'tcx> { } } -/// Used for implied bounds related rules (see rustc guide). +/// Used for implied bounds related rules (see rustc dev guide). trait IntoFromEnvGoal { /// Transforms an existing goal into a `FromEnv` goal. fn into_from_env_goal(self) -> Self; } -/// Used for well-formedness related rules (see rustc guide). +/// Used for well-formedness related rules (see rustc dev guide). trait IntoWellFormedGoal { /// Transforms an existing goal into a `WellFormed` goal. fn into_well_formed_goal(self) -> Self; @@ -178,7 +178,7 @@ crate fn program_clauses_for(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> { fn program_clauses_for_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> { // `trait Trait<P1..Pn> where WC { .. } // P0 == Self` - // Rule Implemented-From-Env (see rustc guide) + // Rule Implemented-From-Env (see rustc dev guide) // // ``` // forall<Self, P1..Pn> { @@ -282,7 +282,7 @@ fn program_clauses_for_impl(tcx: TyCtxt<'tcx>, def_id: DefId) -> Clauses<'tcx> { return List::empty(); } - // Rule Implemented-From-Impl (see rustc guide) + // Rule Implemented-From-Impl (see rustc dev guide) // // `impl<P0..Pn> Trait<A1..An> for A0 where WC { .. }` // @@ -501,7 +501,7 @@ pub fn program_clauses_for_associated_type_def(tcx: TyCtxt<'_>, item_id: DefId) } pub fn program_clauses_for_associated_type_value(tcx: TyCtxt<'_>, item_id: DefId) -> Clauses<'_> { - // Rule Normalize-From-Impl (see rustc guide) + // Rule Normalize-From-Impl (see rustc dev guide) // // ``` // impl<P0..Pn> Trait<A1..An> for A0 { diff --git a/src/librustc_typeck/README.md b/src/librustc_typeck/README.md index fdcbd935524db..b61dbd8c9648e 100644 --- a/src/librustc_typeck/README.md +++ b/src/librustc_typeck/README.md @@ -1,5 +1,5 @@ For high-level intro to how type checking works in rustc, see the -[type checking] chapter of the [rustc guide]. +[type checking] chapter of the [rustc dev guide]. -[type checking]: https://rust-lang.github.io/rustc-guide/type-checking.html -[rustc guide]: https://rust-lang.github.io/rustc-guide/ +[type checking]: https://rustc-dev-guide.rust-lang.org/type-checking.html +[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 542a1ac4536c1..189b05a819bab 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -1,6 +1,6 @@ -//! Method lookup: the secret sauce of Rust. See the [rustc guide] for more information. +//! Method lookup: the secret sauce of Rust. See the [rustc dev guide] for more information. //! -//! [rustc guide]: https://rust-lang.github.io/rustc-guide/method-lookup.html +//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/method-lookup.html mod confirm; pub mod probe; diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs index ddde11b38448b..2684057ccecaf 100644 --- a/src/librustc_typeck/variance/mod.rs +++ b/src/librustc_typeck/variance/mod.rs @@ -1,7 +1,7 @@ -//! Module for inferring the variance of type and lifetime parameters. See the [rustc guide] +//! Module for inferring the variance of type and lifetime parameters. See the [rustc dev guide] //! chapter for more info. //! -//! [rustc guide]: https://rust-lang.github.io/rustc-guide/variance.html +//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/variance.html use hir::Node; use rustc::ty::query::Providers; diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs index dd593a6abb4fe..65bdff3395ddc 100644 --- a/src/librustc_typeck/variance/terms.rs +++ b/src/librustc_typeck/variance/terms.rs @@ -77,8 +77,8 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>( // See the following for a discussion on dep-graph management. // - // - https://rust-lang.github.io/rustc-guide/query.html - // - https://rust-lang.github.io/rustc-guide/variance.html + // - https://rustc-dev-guide.rust-lang.org/query.html + // - https://rustc-dev-guide.rust-lang.org/variance.html tcx.hir().krate().visit_all_item_likes(&mut terms_cx); terms_cx diff --git a/src/librustdoc/README.md b/src/librustdoc/README.md index e4f7bc30e3fcf..5a5f547068d63 100644 --- a/src/librustdoc/README.md +++ b/src/librustdoc/README.md @@ -1,3 +1,3 @@ -For more information about how `librustdoc` works, see the [rustc guide]. +For more information about how `librustdoc` works, see the [rustc dev guide]. -[rustc guide]: https://rust-lang.github.io/rustc-guide/rustdoc.html +[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/rustdoc.html diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 7cb870ae702fb..f600b3308e882 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -12,7 +12,6 @@ use rustc_hir::Mutability; use rustc_metadata::creader::LoadedMacro; use rustc_mir::const_eval::is_min_const_fn; use rustc_span::hygiene::MacroKind; -use rustc_span::symbol::sym; use rustc_span::Span; use crate::clean::{self, GetDefId, ToSource, TypeKind}; diff --git a/src/test/COMPILER_TESTS.md b/src/test/COMPILER_TESTS.md index 3f47ca834cda6..ea540bd0b18a9 100644 --- a/src/test/COMPILER_TESTS.md +++ b/src/test/COMPILER_TESTS.md @@ -1,4 +1,4 @@ # Compiler Test Documentation Documentation for the compiler testing framework can be found in -[the rustc guide](https://rust-lang.github.io/rustc-guide/tests/intro.html). +[the rustc dev guide](https://rustc-dev-guide.rust-lang.org/tests/intro.html). diff --git a/src/test/pretty/issue-12590-a.rs b/src/test/pretty/issue-12590-a.rs index 1a9e85c42d8fb..ca1fef83cffc5 100644 --- a/src/test/pretty/issue-12590-a.rs +++ b/src/test/pretty/issue-12590-a.rs @@ -1,4 +1,5 @@ // pp-exact +// pretty-compare-only // The next line should not be expanded diff --git a/src/test/ui/directory_ownership/macro-expanded-mod.rs b/src/test/ui/directory_ownership/macro-expanded-mod.rs index 376c1a9cd6627..9cb159603a8c5 100644 --- a/src/test/ui/directory_ownership/macro-expanded-mod.rs +++ b/src/test/ui/directory_ownership/macro-expanded-mod.rs @@ -1,7 +1,9 @@ // Test that macro-expanded non-inline modules behave correctly macro_rules! mod_decl { - ($i:ident) => { mod $i; } //~ ERROR Cannot declare a non-inline module inside a block + ($i:ident) => { + mod $i; //~ ERROR Cannot declare a non-inline module inside a block + }; } mod macro_expanded_mod_helper { diff --git a/src/test/ui/directory_ownership/macro-expanded-mod.stderr b/src/test/ui/directory_ownership/macro-expanded-mod.stderr index c7780c869d635..f90419247c92b 100644 --- a/src/test/ui/directory_ownership/macro-expanded-mod.stderr +++ b/src/test/ui/directory_ownership/macro-expanded-mod.stderr @@ -1,8 +1,8 @@ error: Cannot declare a non-inline module inside a block unless it has a path attribute - --> $DIR/macro-expanded-mod.rs:4:25 + --> $DIR/macro-expanded-mod.rs:5:9 | -LL | ($i:ident) => { mod $i; } - | ^^ +LL | mod $i; + | ^^^^^^^ ... LL | mod_decl!(foo); | --------------- in this macro invocation diff --git a/src/test/ui/directory_ownership/non-inline-mod-restriction.stderr b/src/test/ui/directory_ownership/non-inline-mod-restriction.stderr index 46acc7e66d8b8..d034942ca5d4c 100644 --- a/src/test/ui/directory_ownership/non-inline-mod-restriction.stderr +++ b/src/test/ui/directory_ownership/non-inline-mod-restriction.stderr @@ -1,8 +1,8 @@ error: Cannot declare a non-inline module inside a block unless it has a path attribute - --> $DIR/non-inline-mod-restriction.rs:4:9 + --> $DIR/non-inline-mod-restriction.rs:4:5 | LL | mod foo; - | ^^^ + | ^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0583.stderr b/src/test/ui/error-codes/E0583.stderr index ef7a48bc8a48f..073234475e04d 100644 --- a/src/test/ui/error-codes/E0583.stderr +++ b/src/test/ui/error-codes/E0583.stderr @@ -1,8 +1,8 @@ error[E0583]: file not found for module `module_that_doesnt_exist` - --> $DIR/E0583.rs:1:5 + --> $DIR/E0583.rs:1:1 | LL | mod module_that_doesnt_exist; - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: name the file either module_that_doesnt_exist.rs or module_that_doesnt_exist/mod.rs inside the directory "$DIR" diff --git a/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr b/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr index c95df5b4534c1..169fac636f04f 100644 --- a/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr +++ b/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr @@ -1,8 +1,8 @@ error[E0583]: file not found for module `baz` - --> $DIR/auxiliary/foo/bar.rs:1:9 + --> $DIR/auxiliary/foo/bar.rs:1:1 | LL | pub mod baz; - | ^^^ + | ^^^^^^^^^^^^ | = help: name the file either bar/baz.rs or bar/baz/mod.rs inside the directory "$DIR/auxiliary/foo" diff --git a/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod.stderr b/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod.stderr index 98b74e5f5cbca..17ab1c20905da 100644 --- a/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod.stderr +++ b/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod.stderr @@ -1,8 +1,8 @@ error[E0583]: file not found for module `missing` - --> $DIR/foo.rs:4:5 + --> $DIR/foo.rs:4:1 | LL | mod missing; - | ^^^^^^^ + | ^^^^^^^^^^^^ | = help: name the file either foo/missing.rs or foo/missing/mod.rs inside the directory "$DIR" diff --git a/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod_inline.stderr b/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod_inline.stderr index 457e8fcccbfb3..e8abc7376f02f 100644 --- a/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod_inline.stderr +++ b/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod_inline.stderr @@ -1,8 +1,8 @@ error[E0583]: file not found for module `missing` - --> $DIR/foo_inline.rs:4:9 + --> $DIR/foo_inline.rs:4:5 | LL | mod missing; - | ^^^^^^^ + | ^^^^^^^^^^^^ | = help: name the file either missing.rs or missing/mod.rs inside the directory "$DIR/foo_inline/inline" diff --git a/src/test/ui/mod/mod_file_disambig.rs b/src/test/ui/mod/mod_file_disambig.rs index ef203ef082b22..7b182421d34e3 100644 --- a/src/test/ui/mod/mod_file_disambig.rs +++ b/src/test/ui/mod/mod_file_disambig.rs @@ -2,4 +2,5 @@ mod mod_file_disambig_aux; //~ ERROR file for module `mod_file_disambig_aux` fou fn main() { assert_eq!(mod_file_aux::bar(), 10); + //~^ ERROR failed to resolve: use of undeclared type or module `mod_file_aux` } diff --git a/src/test/ui/mod/mod_file_disambig.stderr b/src/test/ui/mod/mod_file_disambig.stderr index 2b77d866fb30b..490633a3fb0ab 100644 --- a/src/test/ui/mod/mod_file_disambig.stderr +++ b/src/test/ui/mod/mod_file_disambig.stderr @@ -1,11 +1,18 @@ error[E0584]: file for module `mod_file_disambig_aux` found at both mod_file_disambig_aux.rs and mod_file_disambig_aux/mod.rs - --> $DIR/mod_file_disambig.rs:1:5 + --> $DIR/mod_file_disambig.rs:1:1 | LL | mod mod_file_disambig_aux; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: delete or rename one of them to remove the ambiguity -error: aborting due to previous error +error[E0433]: failed to resolve: use of undeclared type or module `mod_file_aux` + --> $DIR/mod_file_disambig.rs:4:16 + | +LL | assert_eq!(mod_file_aux::bar(), 10); + | ^^^^^^^^^^^^ use of undeclared type or module `mod_file_aux` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0584`. +Some errors have detailed explanations: E0433, E0584. +For more information about an error, try `rustc --explain E0433`. diff --git a/src/test/ui/parser/circular_modules_main.rs b/src/test/ui/parser/circular_modules_main.rs index b85003bf0910f..1ae36a1f7605e 100644 --- a/src/test/ui/parser/circular_modules_main.rs +++ b/src/test/ui/parser/circular_modules_main.rs @@ -6,5 +6,5 @@ pub fn hi_str() -> String { } fn main() { - circular_modules_hello::say_hello(); + circular_modules_hello::say_hello(); //~ ERROR cannot find function `say_hello` in module } diff --git a/src/test/ui/parser/circular_modules_main.stderr b/src/test/ui/parser/circular_modules_main.stderr index 33865fb7bca95..90f81c64835b7 100644 --- a/src/test/ui/parser/circular_modules_main.stderr +++ b/src/test/ui/parser/circular_modules_main.stderr @@ -1,8 +1,20 @@ error: circular modules: $DIR/circular_modules_hello.rs -> $DIR/circular_modules_main.rs -> $DIR/circular_modules_hello.rs - --> $DIR/circular_modules_main.rs:2:5 + --> $DIR/circular_modules_main.rs:2:1 | LL | mod circular_modules_hello; - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error[E0425]: cannot find function `say_hello` in module `circular_modules_hello` + --> $DIR/circular_modules_main.rs:9:29 + | +LL | circular_modules_hello::say_hello(); + | ^^^^^^^^^ not found in `circular_modules_hello` + | +help: possible candidate is found in another module, you can import it into scope + | +LL | use circular_modules_hello::say_hello; + | + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/parser/issue-5806.stderr b/src/test/ui/parser/issue-5806.stderr index 6cf902ca86e79..bdb5c91ff91eb 100644 --- a/src/test/ui/parser/issue-5806.stderr +++ b/src/test/ui/parser/issue-5806.stderr @@ -1,8 +1,8 @@ error: couldn't read $DIR/../parser: $ACCESS_DENIED_MSG (os error $ACCESS_DENIED_CODE) - --> $DIR/issue-5806.rs:5:5 + --> $DIR/issue-5806.rs:5:1 | LL | mod foo; - | ^^^ + | ^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/parser/mod_file_not_exist.rs b/src/test/ui/parser/mod_file_not_exist.rs index e662c707a38b9..f24b6d5928116 100644 --- a/src/test/ui/parser/mod_file_not_exist.rs +++ b/src/test/ui/parser/mod_file_not_exist.rs @@ -5,4 +5,5 @@ mod not_a_real_file; //~ ERROR file not found for module `not_a_real_file` fn main() { assert_eq!(mod_file_aux::bar(), 10); + //~^ ERROR failed to resolve: use of undeclared type or module `mod_file_aux` } diff --git a/src/test/ui/parser/mod_file_not_exist.stderr b/src/test/ui/parser/mod_file_not_exist.stderr index dadf4b29dcf39..ec05eea66c413 100644 --- a/src/test/ui/parser/mod_file_not_exist.stderr +++ b/src/test/ui/parser/mod_file_not_exist.stderr @@ -1,11 +1,18 @@ error[E0583]: file not found for module `not_a_real_file` - --> $DIR/mod_file_not_exist.rs:3:5 + --> $DIR/mod_file_not_exist.rs:3:1 | LL | mod not_a_real_file; - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ | = help: name the file either not_a_real_file.rs or not_a_real_file/mod.rs inside the directory "$DIR" -error: aborting due to previous error +error[E0433]: failed to resolve: use of undeclared type or module `mod_file_aux` + --> $DIR/mod_file_not_exist.rs:7:16 + | +LL | assert_eq!(mod_file_aux::bar(), 10); + | ^^^^^^^^^^^^ use of undeclared type or module `mod_file_aux` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0583`. +Some errors have detailed explanations: E0433, E0583. +For more information about an error, try `rustc --explain E0433`. diff --git a/src/test/ui/parser/mod_file_with_path_attr.stderr b/src/test/ui/parser/mod_file_with_path_attr.stderr index 004b5d7963a1d..cd1add73d5840 100644 --- a/src/test/ui/parser/mod_file_with_path_attr.stderr +++ b/src/test/ui/parser/mod_file_with_path_attr.stderr @@ -1,8 +1,8 @@ error: couldn't read $DIR/not_a_real_file.rs: $FILE_NOT_FOUND_MSG (os error 2) - --> $DIR/mod_file_with_path_attr.rs:4:5 + --> $DIR/mod_file_with_path_attr.rs:4:1 | LL | mod m; - | ^ + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/parser/stripped-nested-outline-mod-pass.rs b/src/test/ui/parser/stripped-nested-outline-mod-pass.rs new file mode 100644 index 0000000000000..1b4669a439ffe --- /dev/null +++ b/src/test/ui/parser/stripped-nested-outline-mod-pass.rs @@ -0,0 +1,13 @@ +// Expansion drives parsing, so conditional compilation will strip +// out outline modules and we will never attempt parsing them. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +mod foo { + mod bar { + mod baz; // This was an error before. + } +} diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 5fbb986286ade..b389cd0373cc4 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -1,11 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# This script publishes the new "current" toolstate in the toolstate repo (not to be -# confused with publishing the test results, which happens in -# `src/ci/docker/x86_64-gnu-tools/checktools.sh`). -# It is set as callback for `src/ci/docker/x86_64-gnu-tools/repo.sh` by the CI scripts -# when a new commit lands on `master` (i.e., after it passed all checks on `auto`). +# This script computes the new "current" toolstate for the toolstate repo (not to be +# confused with publishing the test results, which happens in `src/bootstrap/toolstate.rs`). +# It gets called from `src/ci/publish_toolstate.sh` when a new commit lands on `master` +# (i.e., after it passed all checks on `auto`). from __future__ import print_function diff --git a/triagebot.toml b/triagebot.toml index a174dd1e7f3fe..13777d7a6c47d 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -17,7 +17,7 @@ Hey LLVM ICE-breakers! This bug has been identified as a good [instructions] for tackling these sorts of bugs. Maybe take a look? Thanks! <3 -[instructions]: https://rust-lang.github.io/rustc-guide/ice-breaker/llvm.html +[instructions]: https://rustc-dev-guide.rust-lang.org/ice-breaker/llvm.html """ label = "ICEBreaker-LLVM" @@ -28,6 +28,6 @@ Hey Cleanup Crew ICE-breakers! This bug has been identified as a good [instructions] for tackling these sorts of bugs. Maybe take a look? Thanks! <3 -[instructions]: https://rust-lang.github.io/rustc-guide/ice-breaker/cleanup-crew.html +[instructions]: https://rustc-dev-guide.rust-lang.org/ice-breaker/cleanup-crew.html """ label = "ICEBreaker-Cleanup-Crew"