Question:
As of the 2021-09-23 nightly, rustc has stopped producing debug output for variables in a specific combination of circumstances: The variable is It is defined in a lib crate. The lib crate is included in a bin crate. The bin crate is built with . We noticed this after bumping past 09-23 to the 2021-10-27 nightly, when our debugger broke. The static is still being included in the ELF output (both allocated space, and represented correctly in the symtab), but is missing from DWARF. Bisecting indicates 2021-09-23 as the culprit (09-22 works). Here is a repro case that I've reduced that works on linux x86-64, at least, and probably other DWARF platforms. modify labels: +regression-from-stable-to-nightly -regression-untriaged
Bumping to regression-stable-to-beta, because 2021-09-23 is a 1.57 nightly. But would be good to confirm this reproduces on beta.
points at (). That being a rollup, looks the most relevant.
Assigning priority as discussed in the of the Prioritization Working Group. label -I-prioritize +P-high
I think this may be a duplicate of . Please test on a current nightly, and when goes out it should have the backport via . It's still possible that introduced its own problem, but maybe it just exacerbated the LLVM issue.
It looks to me like the problem still reoccurs on the current nightly: <details<summaryFor completeness, here is a transcript showing the behavior that is expected, from nightly-2021-09-22</summary</details
This appears to still be reproducing as of ; we're stuck on because basically anything newer breaks our debugger.
So, after working out how to build a toolchain that includes our cross target and rust-lld and whatnot locally, I've tested today's mainline with a revert for PR , commit -- which had previously identified as the likely culprit. I can confirm that DWARF output for our statics on thumbv7em and kin is restored after that commit is reverted. Shall I prepare a PR?

// gdbg-command:print 'basic_types_globals::C' // gdbr-command:print C // gdbg-check:$3 = 97 <del> // gdbr-check:$3 = 97 'a' </del> <ins> // gdbr-check:$3 = 97 </ins> // gdbg-command:print/d 'basic_types_globals::I8' // gdbr-command:print I8 // gdb-check:$4 = 68


Question:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: Also get this using stable: You can see it on the playground: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Can reproduce even without the type aliases: Edit: even smaller reproducer: Produces this output: () :
After some testing, this can be reproduced since 1.53, might have been introduced in

}) .enumerate() .map(|(i, r)| match r { <del> Err(TypeError::Sorts(exp_found)) => Err(TypeError::ArgumentSorts(exp_found, i)), Err(TypeError::Mutability) => Err(TypeError::ArgumentMutability(i)), </del> <ins> Err(TypeError::Sorts(exp_found) | TypeError::ArgumentSorts(exp_found, _)) => { Err(TypeError::ArgumentSorts(exp_found, i)) } Err(TypeError::Mutability | TypeError::ArgumentMutability(_)) => { Err(TypeError::ArgumentMutability(i)) } </ins> r => r, }); Ok(ty::FnSig {


Question:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: Also get this using stable: You can see it on the playground: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Can reproduce even without the type aliases: Edit: even smaller reproducer: Produces this output: () :
After some testing, this can be reproduced since 1.53, might have been introduced in

Ok(()) } <ins> #[instrument(level = "debug", skip(infcx))] </ins> fn extract_spans_for_error_reporting<'a, 'tcx>( infcx: &infer::InferCtxt<'a, 'tcx>, terr: &TypeError<'_>,


Question:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: Also get this using stable: You can see it on the playground: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Can reproduce even without the type aliases: Edit: even smaller reproducer: Produces this output: () :
After some testing, this can be reproduced since 1.53, might have been introduced in

<ins> pub struct A; impl From<fn((), (), &())> for A { fn from(_: fn((), (), &mut ())) -> Self { //~^ error: method `from` has an incompatible type for trait loop {} } } pub struct B; impl From<fn((), (), u32)> for B { fn from(_: fn((), (), u64)) -> Self { //~^ error: method `from` has an incompatible type for trait loop {} } } fn main() {} </ins>


Question:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: Also get this using stable: You can see it on the playground: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Can reproduce even without the type aliases: Edit: even smaller reproducer: Produces this output: () :
After some testing, this can be reproduced since 1.53, might have been introduced in

<ins> error[E0053]: method `from` has an incompatible type for trait --> $DIR/issue-90444.rs:3:16 | LL |     fn from(_: fn((), (), &mut ())) -> Self { |                ^^^^^^^^^^^^^^^^^^^ |                | |                types differ in mutability |                help: change the parameter type to match the trait: `for<'r> fn((), (), &'r ())` | = note: expected fn pointer `fn(for<'r> fn((), (), &'r ())) -> A` found fn pointer `fn(for<'r> fn((), (), &'r mut ())) -> A` error[E0053]: method `from` has an incompatible type for trait --> $DIR/issue-90444.rs:11:16 | LL |     fn from(_: fn((), (), u64)) -> Self { |                ^^^^^^^^^^^^^^^ |                | |                expected `u32`, found `u64` |                help: change the parameter type to match the trait: `fn((), (), u32)` | = note: expected fn pointer `fn(fn((), (), u32)) -> B` found fn pointer `fn(fn((), (), u64)) -> B` error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0053`. </ins>


Question:
This function is only used once, with the current session's directory. Is there a reason to keep it, or should it be replaced by ? Originally posted by in <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
label +A-incr-comp +C-cleanup
feel free to make a PR and r? me on it.
claim

pub fn staging_dep_graph_path(sess: &Session) -> PathBuf { in_incr_comp_dir_sess(sess, STAGING_DEP_GRAPH_FILENAME) } <del> pub fn dep_graph_path_from(incr_comp_session_dir: &Path) -> PathBuf { in_incr_comp_dir(incr_comp_session_dir, DEP_GRAPH_FILENAME) } </del> pub fn work_products_path(sess: &Session) -> PathBuf { in_incr_comp_dir_sess(sess, WORK_PRODUCTS_FILENAME)


Question:
This function is only used once, with the current session's directory. Is there a reason to keep it, or should it be replaced by ? Originally posted by in <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
label +A-incr-comp +C-cleanup
feel free to make a PR and r? me on it.
claim

// Calling `sess.incr_comp_session_dir()` will panic if `sess.opts.incremental.is_none()`. // Fortunately, we just checked that this isn't the case. <del> let path = dep_graph_path_from(&sess.incr_comp_session_dir()); </del> <ins> let path = dep_graph_path(&sess); </ins> let report_incremental_info = sess.opts.debugging_opts.incremental_info; let expected_hash = sess.opts.dep_tracking_hash(false);


Question:
Right now, there are docs for x.py in a bunch of different places: https://rustc-dev- https://rustc-dev- It would be nice to consolidate these some; e.g. can probably just point to the README, and lots of the information in the readme is duplicated in the dev-guide and can be deleted and replaced with a link. cc - do you have strong opinions on this? <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
No, seems good to consolidate. I personally think we might get something out of ending up with two guides, one of which discusses the content from an internal perspective (e.g., Step, how to add new targets) and another from an external perspective, focusing on what users need to know. I think most of the existing documentation is sort of in the second of those, but also (potentially correctly, hard for me to say) treats things as a very leaky abstraction and documents a lot of the internals too. I think some of this is our audience, but I do wonder if a much simpler message is possible with just a few standard commands depending on what they want to build, and documenting specific outputs rather than the whole layout. I think right now we're trying to explain things by teaching everything, but perhaps we can get away with not teaching the internals of the abstraction. Anyway, mostly musing, no strong opinions here.
We should also document that we support suffixes instead of full paths (e.g. instead of ):
Hello, Should I start working on adding doc-comments in bootstrap ?
more doc-comments are always welcome :) but when I wrote the issue I was imagining coming up for a plan for how to organize the standalone documentation. maybe we can put the internal documentation in src/bootstrap/README and the user facing documentation in the guide?
claim
I like the idea and I think this standard should be applied in general since this seperation reduces cost of the maintaince and makes dev-guide more understandable and simple for users. I will follow that idea in the refactoring.

is bootstrapped and in general, some of the technical details of the build system. <del> ## Using rustbuild </del> <ins> Note that this README only covers internal information, not how to use the tool. Please check [bootstrapping dev guide][bootstrapping-dev-guide] for further information. </ins> <del> The rustbuild build system has a primary entry point, a top level `x.py` script: </del> <ins> [bootstrapping-dev-guide]: https://rustc-dev-guide.rust-lang.org/building/bootstrapping.html </ins> <del> ```sh $ python ./x.py build ``` Note that if you're on Unix, you should be able to execute the script directly: ```sh $ ./x.py build ``` The script accepts commands, flags, and arguments to determine what to do: * `build` - a general purpose command for compiling code. Alone, `build` will bootstrap the entire compiler, and otherwise, arguments passed indicate what to build. For example: ``` # build the whole compiler ./x.py build --stage 2 # build the stage1 compiler ./x.py build # build stage0 libstd ./x.py build --stage 0 library/std # build a particular crate in stage0 ./x.py build --stage 0 library/test ``` If files that would normally be rebuilt from stage 0 are dirty, the rebuild can be overridden using `--keep-stage 0`. Using `--keep-stage n` will skip all steps that belong to stage n or earlier: ``` # build stage 1, keeping old build products for stage 0 ./x.py build --keep-stage 0 ``` * `test` - a command for executing unit tests. Like the `build` command, this will execute the entire test suite by default, and otherwise, it can be used to select which test suite is run: ``` # run all unit tests ./x.py test # execute tool tests ./x.py test tidy # execute the UI test suite ./x.py test tests/ui # execute only some tests in the UI test suite ./x.py test tests/ui --test-args substring-of-test-name # execute tests in the standard library in stage0 ./x.py test --stage 0 library/std # execute tests in the core and standard library in stage0, # without running doc tests (thus avoid depending on building the compiler) ./x.py test --stage 0 --no-doc library/core library/std </del> <ins> ## Introduction </ins> <del> # execute all doc tests ./x.py test src/doc ``` </del> <ins> The build system defers most of the complicated logic managing invocations of rustc and rustdoc to Cargo itself. However, moving through various stages and copying artifacts is still necessary for it to do. Each time rustbuild is invoked, it will iterate through the list of predefined steps and execute each serially in turn if it matches the paths passed or is a default rule. For each step rustbuild relies on the step internally being incremental and parallel. Note, though, that the `-j` parameter to rustbuild gets forwarded to appropriate test harnesses and such. </ins> <del> * `doc` - a command for building documentation. Like above, can take arguments for what to document. ## Configuring rustbuild rustbuild offers a TOML-based configuration system with a `config.toml` file. An example of this configuration can be found at `config.toml.example`, and the configuration file can also be passed as `--config path/to/config.toml` if the build system is being invoked manually (via the python script). You can generate a config.toml using `./configure` options if you want to automate creating the file without having to edit it. Finally, rustbuild makes use of the [cc-rs crate] which has [its own method][env-vars] of configuring C compilers and C flags via environment variables. [cc-rs crate]: https://github.com/alexcrichton/cc-rs [env-vars]: https://github.com/alexcrichton/cc-rs#external-configuration-via-environment-variables ## Build stages </del> <ins> ## Build phases </ins> The rustbuild build system goes through a few phases to actually build the compiler. What actually happens when you invoke rustbuild is: <del> 1. The entry point script, `x.py` is run. This script is responsible for downloading the stage0 compiler/Cargo binaries, and it then compiles the build system itself (this folder). Finally, it then invokes the actual `bootstrap` binary build system. </del> <ins> 1. The entry point script(`x` for unix like systems, `x.ps1` for windows systems, `x.py` cross-platform) is run. This script is responsible for downloading the stage0 compiler/Cargo binaries, and it then compiles the build system itself (this folder). Finally, it then invokes the actual `bootstrap` binary build system. </ins> 2. In Rust, `bootstrap` will slurp up all configuration, perform a number of sanity checks (whether compilers exist, for example), and then start building the stage0 artifacts.


Question:
Right now, there are docs for x.py in a bunch of different places: https://rustc-dev- https://rustc-dev- It would be nice to consolidate these some; e.g. can probably just point to the README, and lots of the information in the readme is duplicated in the dev-guide and can be deleted and replaced with a link. cc - do you have strong opinions on this? <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
No, seems good to consolidate. I personally think we might get something out of ending up with two guides, one of which discusses the content from an internal perspective (e.g., Step, how to add new targets) and another from an external perspective, focusing on what users need to know. I think most of the existing documentation is sort of in the second of those, but also (potentially correctly, hard for me to say) treats things as a very leaky abstraction and documents a lot of the internals too. I think some of this is our audience, but I do wonder if a much simpler message is possible with just a few standard commands depending on what they want to build, and documenting specific outputs rather than the whole layout. I think right now we're trying to explain things by teaching everything, but perhaps we can get away with not teaching the internals of the abstraction. Anyway, mostly musing, no strong opinions here.
We should also document that we support suffixes instead of full paths (e.g. instead of ):
Hello, Should I start working on adding doc-comments in bootstrap ?
more doc-comments are always welcome :) but when I wrote the issue I was imagining coming up for a plan for how to organize the standalone documentation. maybe we can put the internal documentation in src/bootstrap/README and the user facing documentation in the guide?
claim
I like the idea and I think this standard should be applied in general since this seperation reduces cost of the maintaince and makes dev-guide more understandable and simple for users. I will follow that idea in the refactoring.

The goal of each stage is to (a) leverage Cargo as much as possible and failing that (b) leverage Rust as much as possible! <del> ## Incremental builds You can configure rustbuild to use incremental compilation with the `--incremental` flag: ```sh $ ./x.py build --incremental ``` The `--incremental` flag will store incremental compilation artifacts in `build/<host>/stage0-incremental`. Note that we only use incremental compilation for the stage0 -> stage1 compilation -- this is because the stage1 compiler is changing, and we don't try to cache and reuse incremental artifacts across different versions of the compiler. You can always drop the `--incremental` to build as normal (but you will still be using the local nightly as your bootstrap). </del> ## Directory Layout This build system houses all output under the `build` directory, which looks


Question:
Right now, there are docs for x.py in a bunch of different places: https://rustc-dev- https://rustc-dev- It would be nice to consolidate these some; e.g. can probably just point to the README, and lots of the information in the readme is duplicated in the dev-guide and can be deleted and replaced with a link. cc - do you have strong opinions on this? <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
No, seems good to consolidate. I personally think we might get something out of ending up with two guides, one of which discusses the content from an internal perspective (e.g., Step, how to add new targets) and another from an external perspective, focusing on what users need to know. I think most of the existing documentation is sort of in the second of those, but also (potentially correctly, hard for me to say) treats things as a very leaky abstraction and documents a lot of the internals too. I think some of this is our audience, but I do wonder if a much simpler message is possible with just a few standard commands depending on what they want to build, and documenting specific outputs rather than the whole layout. I think right now we're trying to explain things by teaching everything, but perhaps we can get away with not teaching the internals of the abstraction. Anyway, mostly musing, no strong opinions here.
We should also document that we support suffixes instead of full paths (e.g. instead of ):
Hello, Should I start working on adding doc-comments in bootstrap ?
more doc-comments are always welcome :) but when I wrote the issue I was imagining coming up for a plan for how to organize the standalone documentation. maybe we can put the internal documentation in src/bootstrap/README and the user facing documentation in the guide?
claim
I like the idea and I think this standard should be applied in general since this seperation reduces cost of the maintaince and makes dev-guide more understandable and simple for users. I will follow that idea in the refactoring.

# system will link (using hard links) output from stageN-{std,rustc} into # each of these directories. # <del> # In theory, there is no extra build output in these directories. </del> <ins> # In theory these are working rustc sysroot directories, meaning there is # no extra build output in these directories. </ins> stage1/ stage2/ stage3/ ``` <del> ## Cargo projects The current build is unfortunately not quite as simple as `cargo build` in a directory, but rather the compiler is split into three different Cargo projects: * `library/std` - the standard library * `library/test` - testing support, depends on libstd * `compiler/rustc` - the actual compiler itself Each "project" has a corresponding Cargo.lock file with all dependencies, and this means that building the compiler involves running Cargo three times. The structure here serves two goals: 1. Facilitating dependencies coming from crates.io. These dependencies don't depend on `std`, so libstd is a separate project compiled ahead of time before the actual compiler builds. 2. Splitting "host artifacts" from "target artifacts". That is, when building code for an arbitrary target, you don't need the entire compiler, but you'll end up needing libraries like libtest that depend on std but also want to use crates.io dependencies. Hence, libtest is split out as its own project that is sequenced after `std` but before `rustc`. This project is built for all targets. There is some loss in build parallelism here because libtest can be compiled in parallel with a number of rustc artifacts, but in theory, the loss isn't too bad! ## Build tools We've actually got quite a few tools that we use in the compiler's build system and for testing. To organize these, each tool is a project in `src/tools` with a corresponding `Cargo.toml`. All tools are compiled with Cargo (currently having independent `Cargo.lock` files) and do not currently explicitly depend on the compiler or standard library. Compiling each tool is sequenced after the appropriate libstd/libtest/librustc compile above. </del> ## Extending rustbuild <del> So, you'd like to add a feature to the rustbuild build system or just fix a bug. Great! One of the major motivational factors for moving away from `make` is that Rust is in theory much easier to read, modify, and write. If you find anything excessively confusing, please open an issue on this, and we'll try to get it documented or simplified, pronto. </del> <ins> When you use the bootstrap system, you'll call it through the entry point script (`x`, `x.ps1`, or `x.py`). However, most of the code lives in `src/bootstrap`. `bootstrap` has a difficult problem: it is written in Rust, but yet it is run before the Rust compiler is built! To work around this, there are two components of bootstrap: the main one written in rust, and `bootstrap.py`. `bootstrap.py` is what gets run by entry point script. It takes care of downloading the `stage0` compiler, which will then build the bootstrap binary written in Rust. </ins> <del> First up, you'll probably want to read over the documentation above, as that'll give you a high level overview of what rustbuild is doing. You also probably want to play around a bit yourself by just getting it up and running before you dive too much into the actual build system itself. </del> <ins> Because there are two separate codebases behind `x.py`, they need to be kept in sync. In particular, both `bootstrap.py` and the bootstrap binary parse `config.toml` and read the same command line arguments. `bootstrap.py` keeps these in sync by setting various environment variables, and the programs sometimes have to add arguments that are explicitly ignored, to be read by the other. </ins> <del> After that, each module in rustbuild should have enough documentation to keep you up and running. Some general areas that you may be interested in modifying are: </del> <ins> Some general areas that you may be interested in modifying are: </ins> * Adding a new build tool? Take a look at `bootstrap/tool.rs` for examples of other tools.


Question:
Right now, there are docs for x.py in a bunch of different places: https://rustc-dev- https://rustc-dev- It would be nice to consolidate these some; e.g. can probably just point to the README, and lots of the information in the readme is duplicated in the dev-guide and can be deleted and replaced with a link. cc - do you have strong opinions on this? <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
No, seems good to consolidate. I personally think we might get something out of ending up with two guides, one of which discusses the content from an internal perspective (e.g., Step, how to add new targets) and another from an external perspective, focusing on what users need to know. I think most of the existing documentation is sort of in the second of those, but also (potentially correctly, hard for me to say) treats things as a very leaky abstraction and documents a lot of the internals too. I think some of this is our audience, but I do wonder if a much simpler message is possible with just a few standard commands depending on what they want to build, and documenting specific outputs rather than the whole layout. I think right now we're trying to explain things by teaching everything, but perhaps we can get away with not teaching the internals of the abstraction. Anyway, mostly musing, no strong opinions here.
We should also document that we support suffixes instead of full paths (e.g. instead of ):
Hello, Should I start working on adding doc-comments in bootstrap ?
more doc-comments are always welcome :) but when I wrote the issue I was imagining coming up for a plan for how to organize the standalone documentation. maybe we can put the internal documentation in src/bootstrap/README and the user facing documentation in the guide?
claim
I like the idea and I think this standard should be applied in general since this seperation reduces cost of the maintaince and makes dev-guide more understandable and simple for users. I will follow that idea in the refactoring.

Changes that do not affect contributors to the compiler or users building rustc from source don't need an update to `VERSION`. <del> If you have any questions, feel free to reach out on the `#t-infra` channel in the [Rust Zulip server][rust-zulip] or ask on internals.rust-lang.org. When you encounter bugs, please file issues on the rust-lang/rust issue tracker. </del> <ins> If you have any questions, feel free to reach out on the `#t-infra/bootstrap` channel at [Rust Bootstrap Zulip server][rust-bootstrap-zulip]. When you encounter bugs, please file issues on the [Rust issue tracker][rust-issue-tracker]. </ins> <del> [rust-zulip]: https://rust-lang.zulipchat.com/#narrow/stream/242791-t-infra </del> <ins> [rust-bootstrap-zulip]: https://rust-lang.zulipchat.com/#narrow/stream/t-infra.2Fbootstrap [rust-issue-tracker]: https://github.com/rust-lang/rust/issues </ins>


Question:
Right now, there are docs for x.py in a bunch of different places: https://rustc-dev- https://rustc-dev- It would be nice to consolidate these some; e.g. can probably just point to the README, and lots of the information in the readme is duplicated in the dev-guide and can be deleted and replaced with a link. cc - do you have strong opinions on this? <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
No, seems good to consolidate. I personally think we might get something out of ending up with two guides, one of which discusses the content from an internal perspective (e.g., Step, how to add new targets) and another from an external perspective, focusing on what users need to know. I think most of the existing documentation is sort of in the second of those, but also (potentially correctly, hard for me to say) treats things as a very leaky abstraction and documents a lot of the internals too. I think some of this is our audience, but I do wonder if a much simpler message is possible with just a few standard commands depending on what they want to build, and documenting specific outputs rather than the whole layout. I think right now we're trying to explain things by teaching everything, but perhaps we can get away with not teaching the internals of the abstraction. Anyway, mostly musing, no strong opinions here.
We should also document that we support suffixes instead of full paths (e.g. instead of ):
Hello, Should I start working on adding doc-comments in bootstrap ?
more doc-comments are always welcome :) but when I wrote the issue I was imagining coming up for a plan for how to organize the standalone documentation. maybe we can put the internal documentation in src/bootstrap/README and the user facing documentation in the guide?
claim
I like the idea and I think this standard should be applied in general since this seperation reduces cost of the maintaince and makes dev-guide more understandable and simple for users. I will follow that idea in the refactoring.

//!   crates.io and Cargo. //! * A standard interface to build across all platforms, including MSVC //! <del> //! ## Architecture //! //! The build system defers most of the complicated logic managing invocations //! of rustc and rustdoc to Cargo itself. However, moving through various stages //! and copying artifacts is still necessary for it to do. Each time rustbuild //! is invoked, it will iterate through the list of predefined steps and execute //! each serially in turn if it matches the paths passed or is a default rule. //! For each step rustbuild relies on the step internally being incremental and //! parallel. Note, though, that the `-j` parameter to rustbuild gets forwarded //! to appropriate test harnesses and such. //! //! Most of the "meaty" steps that matter are backed by Cargo, which does indeed //! have its own parallelism and incremental management. Later steps, like //! tests, aren't incremental and simply run the entire suite currently. //! However, compiletest itself tries to avoid running tests when the artifacts //! that are involved (mainly the compiler) haven't changed. //! //! When you execute `x.py build`, the steps executed are: //! //! * First, the python script is run. This will automatically download the //!   stage0 rustc and cargo according to `src/stage0.json`, or use the cached //!   versions if they're available. These are then used to compile rustbuild //!   itself (using Cargo). Finally, control is then transferred to rustbuild. //! //! * Rustbuild takes over, performs sanity checks, probes the environment, //!   reads configuration, and starts executing steps as it reads the command //!   line arguments (paths) or going through the default rules. //! //!   The build output will be something like the following: //! //!   Building stage0 std artifacts //!   Copying stage0 std //!   Building stage0 test artifacts //!   Copying stage0 test //!   Building stage0 compiler artifacts //!   Copying stage0 rustc //!   Assembling stage1 compiler //!   Building stage1 std artifacts //!   Copying stage1 std //!   Building stage1 test artifacts //!   Copying stage1 test //!   Building stage1 compiler artifacts //!   Copying stage1 rustc //!   Assembling stage2 compiler //!   Uplifting stage1 std //!   Uplifting stage1 test //!   Uplifting stage1 rustc //! //! Let's disect that a little: //! //! ## Building stage0 {std,test,compiler} artifacts //! //! These steps use the provided (downloaded, usually) compiler to compile the //! local Rust source into libraries we can use. //! //! ## Copying stage0 {std,test,rustc} //! //! This copies the build output from Cargo into //! `build/$HOST/stage0-sysroot/lib/rustlib/$ARCH/lib`. FIXME: this step's //! documentation should be expanded -- the information already here may be //! incorrect. //! //! ## Assembling stage1 compiler //! //! This copies the libraries we built in "building stage0 ... artifacts" into //! the stage1 compiler's lib directory. These are the host libraries that the //! compiler itself uses to run. These aren't actually used by artifacts the new //! compiler generates. This step also copies the rustc and rustdoc binaries we //! generated into build/$HOST/stage/bin. //! //! The stage1/bin/rustc is a fully functional compiler, but it doesn't yet have //! any libraries to link built binaries or libraries to. The next 3 steps will //! provide those libraries for it; they are mostly equivalent to constructing //! the stage1/bin compiler so we don't go through them individually. //! //! ## Uplifting stage1 {std,test,rustc} //! //! This step copies the libraries from the stage1 compiler sysroot into the //! stage2 compiler. This is done to avoid rebuilding the compiler; libraries //! we'd build in this step should be identical (in function, if not necessarily //! identical on disk) so there's no need to recompile the compiler again. Note //! that if you want to, you can enable the full-bootstrap option to change this //! behavior. //! //! Each step is driven by a separate Cargo project and rustbuild orchestrates //! copying files between steps and otherwise preparing for Cargo to run. //! </del> //! ## Further information //! //! More documentation can be found in each respective module below, and you can


Question:
I'm seeing an internal compiler error on the following input, found by : The ICE happens after correctly reporting the error "cannot find type in this scope", so low priority. Affected versions: I tried nightly 2021-11-12 and stable 1.56.1 and they both show the same ICE. <details<summary<strongBacktrace</strong</summary<p</p</details
Regressed since , cc
Assigning as and removing .
Another input with a slightly different error message: <details<summary<strongBacktrace</strong</summary<p</p</details
searched nightlies: from nightly-2021-01-07 to nightly-2021-12-24 regressed nightly: nightly-2021-07-26 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.0</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
This regressed in . cc
No longer ICEs since

<ins> fn main() { 2: n([u8; || 1]) //~^ ERROR cannot find type `n` in this scope //~| ERROR mismatched types } </ins>


Question:
I'm seeing an internal compiler error on the following input, found by : The ICE happens after correctly reporting the error "cannot find type in this scope", so low priority. Affected versions: I tried nightly 2021-11-12 and stable 1.56.1 and they both show the same ICE. <details<summary<strongBacktrace</strong</summary<p</p</details
Regressed since , cc
Assigning as and removing .
Another input with a slightly different error message: <details<summary<strongBacktrace</strong</summary<p</p</details
searched nightlies: from nightly-2021-01-07 to nightly-2021-12-24 regressed nightly: nightly-2021-07-26 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.0</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
This regressed in . cc
No longer ICEs since

<ins> error[E0412]: cannot find type `n` in this scope --> $DIR/issue-90871.rs:2:8 | LL |     2: n([u8; || 1]) |        ^ expecting a type here because of type ascription error[E0308]: mismatched types --> $DIR/issue-90871.rs:2:15 | LL |     2: n([u8; || 1]) |               ^^^^ expected `usize`, found closure | = note: expected type `usize` found closure `[closure@$DIR/issue-90871.rs:2:15: 2:17]` help: use parentheses to call this closure | LL |     2: n([u8; (|| 1)()]) |               +    +++ error: aborting due to 2 previous errors Some errors have detailed explanations: E0308, E0412. For more information about an error, try `rustc --explain E0308`. </ins>


Question:
Consider the following code with custom DSTs: The generated assembly for x86_64 is as follows (with my comments ): This can be seen on . Why does the compiler check for zero alignment? It seems that it's impossible, as the alignment cannot be zero. :
Why alignment can't be zero ? Are you sure it's check for alignment ? As I read the asm using for ref: test if is zero, use 1 as default, move rcx if it was not zero. make sense for me but asm is not my field of expertise and even less vtable so I don't really understand why put 1 instead of just move rcx assuming the alignment should be correct but I guess I miss a crucial information about rust internal. I guess is why rust need to test since it's "maybe" sized
Adding gets me So, at least as far as the compiler is concerned, there is no obvious reason it could not be a zero-sized type. I could believe this is a missed optimization, where the compiler could infer that because of the i8 field, it has to be aligned to at least 1, but I do not believe it is a bug. It seems to satisfy the current reasoning around alignment and DSTs.
As stated in , Yes. The references to consist of two pointers, one of with is a base pointer ( in the assembly above) and the second one ( in the assembly above) is the pointer to vtable. The entry of vtable with index (written as in assembly) is the alignment (as it can be seen ).
How does the compilation error above indicate that? Also, ZSTs has alignment 1, as you can check using Why it's not a bug? The compiler generates a seemingly unnecessary instruction, which is an optimization issue. I agree that the issue is quite minor, though, and most probably it doesn't cause observable slowdown. Maybe there are some reasons why the alignment in vtable can be zero, but it seems to contradict the documentation.
I fail to see any explanation in the link that say that, is about the alignment of the vtable not its position or whatever registry contain it. For me it's make more sense it's the size of the object or something, why this code would need the vtable anyway ? It's probably search the alignement of to know the offset of the strucutre: Again just random guess.
It's the alignment of the type corresponding to this vtable, not the alignment of vtable itself. Yes, it is. The issue is that while calculating the offset dynamically, it does redundantly check whether the alignment is zero.
why do you suppose rust internal doesn't need this ? having a zero alignment could mean something like unknown alignment ? I mean you first need to prove test for zero is useless before say it's seem useless. We don't know for sure what Rust really need to do here, the type is dyn, maybe Sized. That not trivial, one should perfectly know Rust internal to know if this check is useless. Sorry for my poor knowledge in this if my comment are just losing your time just ignore them, I just try to understand your point.
I didn't dive into Rust internals code, but I know that the compiler doesn't always check for zero alignment. Here's the example: gives just But, even if I add the transparent wrapper, the check for zero is generated. See the following example: The generated assembly becomes much more complex: I don't have an idea on why the check happens. If it's omitted sometimes, then the compiler kind of knows that the alignment in vtables cannot be zero, yet it generates the check in a more complex example.
I think the diff is caused by versus but you use transparent so here I agree with you it's look strange. You convince me.
This check is generated by the following code: and is used to determine the runtime alignment of the field, which is . In the general case, this check is required, because the alignment of may be 1. You can see this if you change the field in to an , which has 2-byte alignment: In the specific cases you've identified, where the alignment of is 1, I agree that it is unnecessary. When loading alignment from the vtable, we should be adding range metadata to tell LLVM that it's nonzero. (opened for this)

use crate::meth; use crate::traits::*; use rustc_middle::ty::{self, Ty}; <ins> use rustc_target::abi::WrappingRange; </ins> pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx,


Question:
Consider the following code with custom DSTs: The generated assembly for x86_64 is as follows (with my comments ): This can be seen on . Why does the compiler check for zero alignment? It seems that it's impossible, as the alignment cannot be zero. :
Why alignment can't be zero ? Are you sure it's check for alignment ? As I read the asm using for ref: test if is zero, use 1 as default, move rcx if it was not zero. make sense for me but asm is not my field of expertise and even less vtable so I don't really understand why put 1 instead of just move rcx assuming the alignment should be correct but I guess I miss a crucial information about rust internal. I guess is why rust need to test since it's "maybe" sized
Adding gets me So, at least as far as the compiler is concerned, there is no obvious reason it could not be a zero-sized type. I could believe this is a missed optimization, where the compiler could infer that because of the i8 field, it has to be aligned to at least 1, but I do not believe it is a bug. It seems to satisfy the current reasoning around alignment and DSTs.
As stated in , Yes. The references to consist of two pointers, one of with is a base pointer ( in the assembly above) and the second one ( in the assembly above) is the pointer to vtable. The entry of vtable with index (written as in assembly) is the alignment (as it can be seen ).
How does the compilation error above indicate that? Also, ZSTs has alignment 1, as you can check using Why it's not a bug? The compiler generates a seemingly unnecessary instruction, which is an optimization issue. I agree that the issue is quite minor, though, and most probably it doesn't cause observable slowdown. Maybe there are some reasons why the alignment in vtable can be zero, but it seems to contradict the documentation.
I fail to see any explanation in the link that say that, is about the alignment of the vtable not its position or whatever registry contain it. For me it's make more sense it's the size of the object or something, why this code would need the vtable anyway ? It's probably search the alignement of to know the offset of the strucutre: Again just random guess.
It's the alignment of the type corresponding to this vtable, not the alignment of vtable itself. Yes, it is. The issue is that while calculating the offset dynamically, it does redundantly check whether the alignment is zero.
why do you suppose rust internal doesn't need this ? having a zero alignment could mean something like unknown alignment ? I mean you first need to prove test for zero is useless before say it's seem useless. We don't know for sure what Rust really need to do here, the type is dyn, maybe Sized. That not trivial, one should perfectly know Rust internal to know if this check is useless. Sorry for my poor knowledge in this if my comment are just losing your time just ignore them, I just try to understand your point.
I didn't dive into Rust internals code, but I know that the compiler doesn't always check for zero alignment. Here's the example: gives just But, even if I add the transparent wrapper, the check for zero is generated. See the following example: The generated assembly becomes much more complex: I don't have an idea on why the check happens. If it's omitted sometimes, then the compiler kind of knows that the alignment in vtables cannot be zero, yet it generates the check in a more complex example.
I think the diff is caused by versus but you use transparent so here I agree with you it's look strange. You convince me.
This check is generated by the following code: and is used to determine the runtime alignment of the field, which is . In the general case, this check is required, because the alignment of may be 1. You can see this if you change the field in to an , which has 2-byte alignment: In the specific cases you've identified, where the alignment of is 1, I agree that it is unnecessary. When loading alignment from the vtable, we should be adding range metadata to tell LLVM that it's nonzero. (opened for this)

} match t.kind() { ty::Dynamic(..) => { <del> // load size/align from vtable </del> <ins> // Load size/align from vtable. </ins> let vtable = info.unwrap(); <del> ( meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_SIZE) .get_usize(bx, vtable), meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_ALIGN) .get_usize(bx, vtable), ) </del> <ins> let size = meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_SIZE) .get_usize(bx, vtable); let align = meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_ALIGN) .get_usize(bx, vtable); // Alignment is always nonzero. bx.range_metadata(align, WrappingRange { start: 1, end: !0 }); (size, align) </ins> } ty::Slice(_) | ty::Str => { let unit = layout.field(bx, 0);


Question:
Consider the following code with custom DSTs: The generated assembly for x86_64 is as follows (with my comments ): This can be seen on . Why does the compiler check for zero alignment? It seems that it's impossible, as the alignment cannot be zero. :
Why alignment can't be zero ? Are you sure it's check for alignment ? As I read the asm using for ref: test if is zero, use 1 as default, move rcx if it was not zero. make sense for me but asm is not my field of expertise and even less vtable so I don't really understand why put 1 instead of just move rcx assuming the alignment should be correct but I guess I miss a crucial information about rust internal. I guess is why rust need to test since it's "maybe" sized
Adding gets me So, at least as far as the compiler is concerned, there is no obvious reason it could not be a zero-sized type. I could believe this is a missed optimization, where the compiler could infer that because of the i8 field, it has to be aligned to at least 1, but I do not believe it is a bug. It seems to satisfy the current reasoning around alignment and DSTs.
As stated in , Yes. The references to consist of two pointers, one of with is a base pointer ( in the assembly above) and the second one ( in the assembly above) is the pointer to vtable. The entry of vtable with index (written as in assembly) is the alignment (as it can be seen ).
How does the compilation error above indicate that? Also, ZSTs has alignment 1, as you can check using Why it's not a bug? The compiler generates a seemingly unnecessary instruction, which is an optimization issue. I agree that the issue is quite minor, though, and most probably it doesn't cause observable slowdown. Maybe there are some reasons why the alignment in vtable can be zero, but it seems to contradict the documentation.
I fail to see any explanation in the link that say that, is about the alignment of the vtable not its position or whatever registry contain it. For me it's make more sense it's the size of the object or something, why this code would need the vtable anyway ? It's probably search the alignement of to know the offset of the strucutre: Again just random guess.
It's the alignment of the type corresponding to this vtable, not the alignment of vtable itself. Yes, it is. The issue is that while calculating the offset dynamically, it does redundantly check whether the alignment is zero.
why do you suppose rust internal doesn't need this ? having a zero alignment could mean something like unknown alignment ? I mean you first need to prove test for zero is useless before say it's seem useless. We don't know for sure what Rust really need to do here, the type is dyn, maybe Sized. That not trivial, one should perfectly know Rust internal to know if this check is useless. Sorry for my poor knowledge in this if my comment are just losing your time just ignore them, I just try to understand your point.
I didn't dive into Rust internals code, but I know that the compiler doesn't always check for zero alignment. Here's the example: gives just But, even if I add the transparent wrapper, the check for zero is generated. See the following example: The generated assembly becomes much more complex: I don't have an idea on why the check happens. If it's omitted sometimes, then the compiler kind of knows that the alignment in vtables cannot be zero, yet it generates the check in a more complex example.
I think the diff is caused by versus but you use transparent so here I agree with you it's look strange. You convince me.
This check is generated by the following code: and is used to determine the runtime alignment of the field, which is . In the general case, this check is required, because the alignment of may be 1. You can see this if you change the field in to an , which has 2-byte alignment: In the specific cases you've identified, where the alignment of is 1, I agree that it is unnecessary. When loading alignment from the vtable, we should be adding range metadata to tell LLVM that it's nonzero. (opened for this)

<ins> // compile-flags: -O #![crate_type = "lib"] // This test checks that we annotate alignment loads from vtables with nonzero range metadata, // and that this allows LLVM to eliminate redundant `align >= 1` checks. pub trait Trait { fn f(&self); } pub struct WrapperWithAlign1<T: ?Sized> { x: u8, y: T } pub struct WrapperWithAlign2<T: ?Sized> { x: u16, y: T } pub struct Struct<W: ?Sized> { _field: i8, dst: W, } // CHECK-LABEL: @eliminates_runtime_check_when_align_1 #[no_mangle] pub fn eliminates_runtime_check_when_align_1( x: &Struct<WrapperWithAlign1<dyn Trait>> ) -> &WrapperWithAlign1<dyn Trait> { // CHECK: load [[USIZE:i[0-9]+]], {{.+}} !range [[RANGE_META:![0-9]+]] // CHECK-NOT: icmp // CHECK-NOT: select // CHECK: ret &x.dst } // CHECK-LABEL: @does_not_eliminate_runtime_check_when_align_2 #[no_mangle] pub fn does_not_eliminate_runtime_check_when_align_2( x: &Struct<WrapperWithAlign2<dyn Trait>> ) -> &WrapperWithAlign2<dyn Trait> { // CHECK: [[X0:%[0-9]+]] = load [[USIZE]], {{.+}} !range [[RANGE_META]] // CHECK: [[X1:%[0-9]+]] = icmp {{.+}} [[X0]] // CHECK: [[X2:%[0-9]+]] = select {{.+}} [[X1]] // CHECK: ret &x.dst } // CHECK: [[RANGE_META]] = !{[[USIZE]] 1, [[USIZE]] 0} </ins>


Question:
I've rebased this morning and I can't build the repo anymore since landed. It seems there are missing tools in the LLVM CI tarball. AFAICT, these are the tools CI copies in the tarball: And these are the tools bootstrap tries to install in : being defined as: As you can see, there are many tools in that are not included in that step shown above. I'm on macOS, and here is the list of tools that I found in the downloaded LLVM CI tarball: Cc who authored .
I think we should disable copying those tools under ci-llvm for now, and then decide if we want to include them in the ci-llvm artifact or not.
makes sense to me!
Actually the problem seems to be bigger, for now I disabled using the LLVM CI tarball locally and it still failed.
What error are you getting with it disabled?
Exactly the same. I restarted the whole build after running , I'll report back once (if) the error reproduces again.
Ah! The compiler profile sets to , my bad, I'll explicitly override that to in my config and the problem will probably go away. I should have noticed I didn't actually rebuild LLVM hah.
I'll open a PR to make copying the tools conditional on LLVM being built locally.
Or just call , like I suggested originally ... I'm not sure why dist is being treated differently from all the other build commands.
Those tools don't exist in the downloaded archive, so won't help here

// (e.g. the `bootimage` crate). for tool in LLVM_TOOLS { let tool_exe = exe(tool, target_compiler.host); <del> builder.copy(&llvm_bin_dir.join(&tool_exe), &libdir_bin.join(&tool_exe)); </del> <ins> let src_path = llvm_bin_dir.join(&tool_exe); // When using `donwload-ci-llvm`, some of the tools // may not exist, so skip trying to copy them. if src_path.exists() { builder.copy(&src_path, &libdir_bin.join(&tool_exe)); } </ins> } } }


Question:
The following code works in 1.56.0 but crashes 1.57.0 as well as the most recent nightly — . <details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
According to cargo-bisect-rustc the regression is from — FYI regressed nightly: nightly-2021-09-06 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.1</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
Seems that this is duplicate of and ; only triggers with incremental compilation enabled. Unfortunately although I authored the original PR, I don't know a lot about incr-comp or the query system to diagnostic the issue. label: +A-incr-comp
Found the bug, I'll put up a PR in a sec. claim
reopening as this is a stable-to-stable regression, and (I think) we keep those open until a fix lands on stable or we explicitly decline to fix.
was this backported / can we close the issue? :)
The fix was backported and released in 1.58.0
Perfect, thanks for checking !

impl<CTX> HashStable<CTX> for InferTy { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { use InferTy::*; <ins> discriminant(self).hash_stable(ctx, hasher); </ins> match self { TyVar(v) => v.as_u32().hash_stable(ctx, hasher), IntVar(v) => v.index.hash_stable(ctx, hasher),


Question:
The following code works in 1.56.0 but crashes 1.57.0 as well as the most recent nightly — . <details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
According to cargo-bisect-rustc the regression is from — FYI regressed nightly: nightly-2021-09-06 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.1</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
Seems that this is duplicate of and ; only triggers with incremental compilation enabled. Unfortunately although I authored the original PR, I don't know a lot about incr-comp or the query system to diagnostic the issue. label: +A-incr-comp
Found the bug, I'll put up a PR in a sec. claim
reopening as this is a stable-to-stable regression, and (I think) we keep those open until a fix lands on stable or we explicitly decline to fix.
was this backported / can we close the issue? :)
The fix was backported and released in 1.58.0
Perfect, thanks for checking !

<ins> // check-pass // incremental struct Struct<T>(T); impl<T> std::ops::Deref for Struct<T> { type Target = dyn Fn(T); fn deref(&self) -> &Self::Target { unimplemented!() } } fn main() { let f = Struct(Default::default()); f(0); f(0); } </ins>


Question:
contains two sets of methods to access the Arc's wrapped object. and are tagged unsafe as "it is possible to construct a circular reference among multiple Arcs by mutating the underlying data. This creates potential for deadlock, but worse, this will guarantee a memory leak of all involved Arcs." There are also and methods defined when the inner type is freezable as that guarantees the type can't contain a . However, it's still trivially easy to deadlock using the safe methods: It seems that the consensus in was that possibility of deadlock is inherently unsafe, so should and be removed? cc
Perhaps access should fail when it is called by the same task twice? It would be nice if people didn't have to use unsafe blocks just to get normal stuff done.
Nested locks in the same task aren't the only way you can run into deadlock:
I am aware of that, but it seems to me this particular error would be easy and cheap to catch, so if we aren't doing that yet, we probably should. Personally I don't think the possibility of a deadlock should require an unsafe block.
Consensus in the past has been that deadlock is not unsafe (). You can deadlock with pipes too, with just two lines of code. The non- accessors for are unsafe for a totally different reason, which is documented in . Regarding "cheap and easy to catch" - I don't believe we should try to fail in the single-task deadlock case unless we can reliably fail in all deadlock cases (which is not out of the question but requires scheduler support, see ). A user who is used to seeing a failure message from their previous attempts which had deadlocked would be all the more confused when they find their cross-task deadlocking code does not fail.
Is the possibility of memory leakage really considered unsafe? doesn't seem to share that assumption, but I may be missing something there.
Neither or provides a way to leak memory via the safe constructors.
We currently don't officially consider leaks to be , but I think leaking past the lifetime of tasks with references is a very questionable thing to allow.
The box annihilator is not a good solution to rc reference cycles, but it is at least a solution. Cycles of MutexArcs will produce valgrind errors.
now provides a way to leak with the safe constructors.

* other tasks wishing to access the data will block until the closure * finishes running. * <del> * The reason this function is 'unsafe' is because it is possible to * construct a circular reference among multiple Arcs by mutating the * underlying data. This creates potential for deadlock, but worse, this * will guarantee a memory leak of all involved Arcs. Using MutexArcs * inside of other Arcs is safe in absence of circular references. * </del> * If you wish to nest MutexArcs, one strategy for ensuring safety at * runtime is to add a "nesting level counter" inside the stored data, and * when traversing the arcs, assert that they monotonically decrease.


Question:
contains two sets of methods to access the Arc's wrapped object. and are tagged unsafe as "it is possible to construct a circular reference among multiple Arcs by mutating the underlying data. This creates potential for deadlock, but worse, this will guarantee a memory leak of all involved Arcs." There are also and methods defined when the inner type is freezable as that guarantees the type can't contain a . However, it's still trivially easy to deadlock using the safe methods: It seems that the consensus in was that possibility of deadlock is inherently unsafe, so should and be removed? cc
Perhaps access should fail when it is called by the same task twice? It would be nice if people didn't have to use unsafe blocks just to get normal stuff done.
Nested locks in the same task aren't the only way you can run into deadlock:
I am aware of that, but it seems to me this particular error would be easy and cheap to catch, so if we aren't doing that yet, we probably should. Personally I don't think the possibility of a deadlock should require an unsafe block.
Consensus in the past has been that deadlock is not unsafe (). You can deadlock with pipes too, with just two lines of code. The non- accessors for are unsafe for a totally different reason, which is documented in . Regarding "cheap and easy to catch" - I don't believe we should try to fail in the single-task deadlock case unless we can reliably fail in all deadlock cases (which is not out of the question but requires scheduler support, see ). A user who is used to seeing a failure message from their previous attempts which had deadlocked would be all the more confused when they find their cross-task deadlocking code does not fail.
Is the possibility of memory leakage really considered unsafe? doesn't seem to share that assumption, but I may be missing something there.
Neither or provides a way to leak memory via the safe constructors.
We currently don't officially consider leaks to be , but I think leaking past the lifetime of tasks with references is a very questionable thing to allow.
The box annihilator is not a good solution to rc reference cycles, but it is at least a solution. Cycles of MutexArcs will produce valgrind errors.
now provides a way to leak with the safe constructors.

* blocked on the mutex) will also fail immediately. */ #[inline] <del> pub unsafe fn unsafe_access<U>(&self, blk: |x: &mut T| -> U) -> U { </del> <ins> pub fn access<U>(&self, blk: |x: &mut T| -> U) -> U { </ins> let state = self.x.get(); <del> // Borrowck would complain about this if the function were // not already unsafe. See borrow_rwlock, far below. (&(*state).lock).lock(|| { check_poison(true, (*state).failed); let _z = PoisonOnFail::new(&mut (*state).failed); blk(&mut (*state).data) }) </del> <ins> unsafe { // Borrowck would complain about this if the code were // not already unsafe. See borrow_rwlock, far below. (&(*state).lock).lock(|| { check_poison(true, (*state).failed); let _z = PoisonOnFail::new(&mut (*state).failed); blk(&mut (*state).data) }) } </ins> } <del> /// As unsafe_access(), but with a condvar, as sync::mutex.lock_cond(). </del> <ins> /// As access(), but with a condvar, as sync::mutex.lock_cond(). </ins> #[inline] <del> pub unsafe fn unsafe_access_cond<U>(&self, blk: |x: &mut T, c: &Condvar| -> U) -> U { </del> <ins> pub fn access_cond<U>(&self, blk: |x: &mut T, c: &Condvar| -> U) -> U { </ins> let state = self.x.get(); <del> (&(*state).lock).lock_cond(|cond| { check_poison(true, (*state).failed); let _z = PoisonOnFail::new(&mut (*state).failed); blk(&mut (*state).data, &Condvar {is_mutex: true, failed: &(*state).failed, cond: cond }) }) } } impl<T:Freeze + Send> MutexArc<T> { /** * As unsafe_access. * * The difference between access and unsafe_access is that the former * forbids mutexes to be nested. While unsafe_access can be used on * MutexArcs without freezable interiors, this safe version of access * requires the Freeze bound, which prohibits access on MutexArcs which * might contain nested MutexArcs inside. * * The purpose of this is to offer a safe implementation of MutexArc to be * used instead of RWArc in cases where no readers are needed and slightly * better performance is required. * * Both methods have the same failure behaviour as unsafe_access and * unsafe_access_cond. */ #[inline] pub fn access<U>(&self, blk: |x: &mut T| -> U) -> U { unsafe { self.unsafe_access(blk) } } /// As unsafe_access_cond but safe and Freeze. #[inline] pub fn access_cond<U>(&self, blk: |x: &mut T, c: &Condvar| -> U) -> U { unsafe { self.unsafe_access_cond(blk) } </del> <ins> unsafe { (&(*state).lock).lock_cond(|cond| { check_poison(true, (*state).failed); let _z = PoisonOnFail::new(&mut (*state).failed); blk(&mut (*state).data, &Condvar {is_mutex: true, failed: &(*state).failed, cond: cond }) }) } </ins> } }


Question:
contains two sets of methods to access the Arc's wrapped object. and are tagged unsafe as "it is possible to construct a circular reference among multiple Arcs by mutating the underlying data. This creates potential for deadlock, but worse, this will guarantee a memory leak of all involved Arcs." There are also and methods defined when the inner type is freezable as that guarantees the type can't contain a . However, it's still trivially easy to deadlock using the safe methods: It seems that the consensus in was that possibility of deadlock is inherently unsafe, so should and be removed? cc
Perhaps access should fail when it is called by the same task twice? It would be nice if people didn't have to use unsafe blocks just to get normal stuff done.
Nested locks in the same task aren't the only way you can run into deadlock:
I am aware of that, but it seems to me this particular error would be easy and cheap to catch, so if we aren't doing that yet, we probably should. Personally I don't think the possibility of a deadlock should require an unsafe block.
Consensus in the past has been that deadlock is not unsafe (). You can deadlock with pipes too, with just two lines of code. The non- accessors for are unsafe for a totally different reason, which is documented in . Regarding "cheap and easy to catch" - I don't believe we should try to fail in the single-task deadlock case unless we can reliably fail in all deadlock cases (which is not out of the question but requires scheduler support, see ). A user who is used to seeing a failure message from their previous attempts which had deadlocked would be all the more confused when they find their cross-task deadlocking code does not fail.
Is the possibility of memory leakage really considered unsafe? doesn't seem to share that assumption, but I may be missing something there.
Neither or provides a way to leak memory via the safe constructors.
We currently don't officially consider leaks to be , but I think leaking past the lifetime of tasks with references is a very questionable thing to allow.
The box annihilator is not a good solution to rc reference cycles, but it is at least a solution. Cycles of MutexArcs will produce valgrind errors.
now provides a way to leak with the safe constructors.

impl<T:Clone+Send+Freeze> Clone for CowArc<T> { /// Duplicate a Copy-on-write Arc. See arc::clone for more details. <del> #[inline] </del> fn clone(&self) -> CowArc<T> { CowArc { x: self.x.clone() } }


Question:
contains two sets of methods to access the Arc's wrapped object. and are tagged unsafe as "it is possible to construct a circular reference among multiple Arcs by mutating the underlying data. This creates potential for deadlock, but worse, this will guarantee a memory leak of all involved Arcs." There are also and methods defined when the inner type is freezable as that guarantees the type can't contain a . However, it's still trivially easy to deadlock using the safe methods: It seems that the consensus in was that possibility of deadlock is inherently unsafe, so should and be removed? cc
Perhaps access should fail when it is called by the same task twice? It would be nice if people didn't have to use unsafe blocks just to get normal stuff done.
Nested locks in the same task aren't the only way you can run into deadlock:
I am aware of that, but it seems to me this particular error would be easy and cheap to catch, so if we aren't doing that yet, we probably should. Personally I don't think the possibility of a deadlock should require an unsafe block.
Consensus in the past has been that deadlock is not unsafe (). You can deadlock with pipes too, with just two lines of code. The non- accessors for are unsafe for a totally different reason, which is documented in . Regarding "cheap and easy to catch" - I don't believe we should try to fail in the single-task deadlock case unless we can reliably fail in all deadlock cases (which is not out of the question but requires scheduler support, see ). A user who is used to seeing a failure message from their previous attempts which had deadlocked would be all the more confused when they find their cross-task deadlocking code does not fail.
Is the possibility of memory leakage really considered unsafe? doesn't seem to share that assumption, but I may be missing something there.
Neither or provides a way to leak memory via the safe constructors.
We currently don't officially consider leaks to be , but I think leaking past the lifetime of tasks with references is a very questionable thing to allow.
The box annihilator is not a good solution to rc reference cycles, but it is at least a solution. Cycles of MutexArcs will produce valgrind errors.
now provides a way to leak with the safe constructors.

} #[test] <del> fn test_unsafe_mutex_arc_nested() { unsafe { // Tests nested mutexes and access // to underlaying data. let arc = ~MutexArc::new(1); let arc2 = ~MutexArc::new(*arc); task::spawn(proc() { (*arc2).unsafe_access(|mutex| { (*mutex).access(|one| { assert!(*one == 1); }) </del> <ins> fn test_mutex_arc_nested() { // Tests nested mutexes and access // to underlaying data. let arc = ~MutexArc::new(1); let arc2 = ~MutexArc::new(*arc); task::spawn(proc() { (*arc2).access(|mutex| { (*mutex).access(|one| { assert!(*one == 1); </ins> }) <del> }); } </del> <ins> }) }); </ins> } #[test]


Question:
contains two sets of methods to access the Arc's wrapped object. and are tagged unsafe as "it is possible to construct a circular reference among multiple Arcs by mutating the underlying data. This creates potential for deadlock, but worse, this will guarantee a memory leak of all involved Arcs." There are also and methods defined when the inner type is freezable as that guarantees the type can't contain a . However, it's still trivially easy to deadlock using the safe methods: It seems that the consensus in was that possibility of deadlock is inherently unsafe, so should and be removed? cc
Perhaps access should fail when it is called by the same task twice? It would be nice if people didn't have to use unsafe blocks just to get normal stuff done.
Nested locks in the same task aren't the only way you can run into deadlock:
I am aware of that, but it seems to me this particular error would be easy and cheap to catch, so if we aren't doing that yet, we probably should. Personally I don't think the possibility of a deadlock should require an unsafe block.
Consensus in the past has been that deadlock is not unsafe (). You can deadlock with pipes too, with just two lines of code. The non- accessors for are unsafe for a totally different reason, which is documented in . Regarding "cheap and easy to catch" - I don't believe we should try to fail in the single-task deadlock case unless we can reliably fail in all deadlock cases (which is not out of the question but requires scheduler support, see ). A user who is used to seeing a failure message from their previous attempts which had deadlocked would be all the more confused when they find their cross-task deadlocking code does not fail.
Is the possibility of memory leakage really considered unsafe? doesn't seem to share that assumption, but I may be missing something there.
Neither or provides a way to leak memory via the safe constructors.
We currently don't officially consider leaks to be , but I think leaking past the lifetime of tasks with references is a very questionable thing to allow.
The box annihilator is not a good solution to rc reference cycles, but it is at least a solution. Cycles of MutexArcs will produce valgrind errors.
now provides a way to leak with the safe constructors.

<del> // Copyright 2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. extern crate sync; use std::task; use sync::MutexArc; fn test_mutex_arc_nested() { let arc = ~MutexArc::new(1); let arc2 = ~MutexArc::new(*arc); task::spawn(proc() { (*arc2).access(|mutex| { //~ ERROR instantiating a type parameter with an incompatible type }) }); } fn main() {} </del>