diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f921fb2c94233..c3054460545d1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,8 +1,8 @@ # Contributing to Rust Thank you for your interest in contributing to Rust! There are many ways to -contribute, and we appreciate all of them. This document is a bit long, so here's -links to the major sections: +contribute, and we appreciate all of them. This document is a bit long, so here +are some links to the major sections: * [Feature Requests](#feature-requests) * [Bug Reports](#bug-reports) @@ -13,10 +13,12 @@ links to the major sections: * [Out-of-tree Contributions](#out-of-tree-contributions) * [Helpful Links and Information](#helpful-links-and-information) -If you have questions, please make a post on [internals.rust-lang.org][internals] or -hop on [#rust-internals][pound-rust-internals]. +If you have questions, please make a post on +[internals.rust-lang.org][internals] or hop on +[#rust-internals][pound-rust-internals]. -As a reminder, all contributors are expected to follow our [Code of Conduct][coc]. +As a reminder, all contributors are expected to follow our +[Code of Conduct][coc]. [pound-rust-internals]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-internals [internals]: https://internals.rust-lang.org @@ -35,14 +37,15 @@ While bugs are unfortunate, they're a reality in software. We can't fix what we don't know about, so please report liberally. If you're not sure if something is a bug or not, feel free to file a bug anyway. -**If you believe reporting your bug publicly represents a security risk to Rust users, -please follow our [instructions for reporting security vulnerabilities](https://www.rust-lang.org/security.html)**. +**If you believe reporting your bug publicly represents a security risk to Rust +users, please follow our [instructions for reporting security vulnerabilities] +(https://www.rust-lang.org/security.html)**. If you have the chance, before reporting a bug, please [search existing issues](https://github.com/rust-lang/rust/search?q=&type=Issues&utf8=%E2%9C%93), as it's possible that someone else has already reported your error. This doesn't -always work, and sometimes it's hard to know what to search for, so consider this -extra credit. We won't mind if you accidentally file a duplicate report. +always work, and sometimes it's hard to know what to search for, so consider +this extra credit. We won't mind if you accidentally file a duplicate report. Opening an issue is as easy as following [this link](https://github.com/rust-lang/rust/issues/new) and filling out the fields. @@ -99,12 +102,12 @@ Before you can start building the compiler you need to configure the build for your system. In most cases, that will just mean using the defaults provided for Rust. -To change configuration, you must copy the file `src/bootstrap/config.toml.example` -to `config.toml` in the directory from which you will be running the build, and -change the settings provided. +To change configuration, you must copy the file +`src/bootstrap/config.toml.example` to `config.toml` in the directory from which +you will be running the build, and change the settings provided. -There are large number of options provided in this config file that will alter the -configuration used in the build process. Some options to note: +There are large number of options provided in this config file that will alter +the configuration used in the build process. Some options to note: #### `[llvm]`: - `ccache = true` - Use ccache when building llvm @@ -114,7 +117,8 @@ configuration used in the build process. Some options to note: #### `[rust]`: - `debuginfo = true` - Build a compiler with debuginfo -- `optimize = false` - Disable optimizations to speed up compilation of stage1 rust +- `optimize = false` - Disable optimizations to speed up compilation of stage1 + rust For more options, the `config.toml` file contains commented out defaults, with descriptions of what each option will do. @@ -126,9 +130,9 @@ file. If you still have a `config.mk` file in your directory - from ### Building -The build system uses the `x.py` script to control the build process. This script -is used to build, test, and document various parts of the compiler. You can -execute it as: +The build system uses the `x.py` script to control the build process. This +script is used to build, test, and document various parts of the compiler. You +can execute it as: ```sh python x.py build @@ -262,7 +266,8 @@ guidelines by running $ python x.py test src/tools/tidy Make this check before every pull request (and every new commit in a pull -request) ; you can add [git hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) +request) ; you can add +[git hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) before every push to make sure you never forget to make this check. All pull requests are reviewed by another person. We have a bot, @@ -305,20 +310,20 @@ though you may see a slightly different form of `r+`: @bors: r+ 38fe8d2 rollup -That additional `rollup` tells @bors that this change is eligible for a 'rollup'. -To save @bors some work, and to get small changes through more quickly, when -@bors attempts to merge a commit that's rollup-eligible, it will also merge -the other rollup-eligible patches too, and they'll get tested and merged at -the same time. +That additional `rollup` tells @bors that this change is eligible for a +'rollup'. To save @bors some work, and to get small changes through more +quickly, when @bors attempts to merge a commit that's rollup-eligible, it will +also merge the other rollup-eligible patches too, and they'll get tested and +merged at the same time. To find documentation-related issues, sort by the [A-docs label][adocs]. [adocs]: https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AA-docs -In many cases, you don't need a full `./x.py doc`. You can use `rustdoc` directly -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. +In many cases, you don't need a full `./x.py doc`. You can use `rustdoc` +directly 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. ## Issue Triage @@ -392,12 +397,15 @@ are: * The [Rust Internals forum][rif], a place to ask questions and discuss Rust's internals * The [generated documentation for rust's compiler][gdfrustc] -* The [rust reference][rr], even though it doesn't specifically talk about Rust's internals, it's a great resource nonetheless +* The [rust reference][rr], even though it doesn't specifically talk about + Rust's internals, it's a great resource nonetheless * Although out of date, [Tom Lee's great blog article][tlgba] is very helpful * [rustaceans.org][ro] is helpful, but mostly dedicated to IRC * The [Rust Compiler Testing Docs][rctd] -* For @bors, [this cheat sheet][cheatsheet] is helpful (Remember to replace `@homu` with `@bors` in the commands that you use.) -* **Google!** ([search only in Rust Documentation][gsearchdocs] to find types, traits, etc. quickly) +* For @bors, [this cheat sheet][cheatsheet] is helpful (Remember to replace + `@homu` with `@bors` in the commands that you use.) +* **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. [gdfrustc]: http://manishearth.github.io/rust-internals-docs/rustc/ diff --git a/COPYRIGHT b/COPYRIGHT index abe8998030871..c12ed2f4afc77 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -6,8 +6,7 @@ terms. Longer version: -The Rust Project is copyright 2010, The Rust Project -Developers. +The Rust Project is copyright 2010, The Rust Project Developers. Licensed under the Apache License, Version 2.0 ::`[`sort_by_key`] * checked, saturated, and overflowing operations - * [`i32::checked_rem`], [`i32::checked_neg`], [`i32::checked_shl`], [`i32::checked_shr`] + * [`i32::checked_rem`], [`i32::checked_neg`], [`i32::checked_shl`], + [`i32::checked_shr`] * [`i32::saturating_mul`] - * [`i32::overflowing_add`], [`i32::overflowing_sub`], [`i32::overflowing_mul`], [`i32::overflowing_div`] - * [`i32::overflowing_rem`], [`i32::overflowing_neg`], [`i32::overflowing_shl`], [`i32::overflowing_shr`] - * [`u32::checked_rem`], [`u32::checked_neg`], [`u32::checked_shl`], [`u32::checked_shl`] + * [`i32::overflowing_add`], [`i32::overflowing_sub`], + [`i32::overflowing_mul`], [`i32::overflowing_div`] + * [`i32::overflowing_rem`], [`i32::overflowing_neg`], + [`i32::overflowing_shl`], [`i32::overflowing_shr`] + * [`u32::checked_rem`], [`u32::checked_neg`], [`u32::checked_shl`], + [`u32::checked_shl`] * [`u32::saturating_mul`] - * [`u32::overflowing_add`], [`u32::overflowing_sub`], [`u32::overflowing_mul`], [`u32::overflowing_div`] - * [`u32::overflowing_rem`], [`u32::overflowing_neg`], [`u32::overflowing_shl`], [`u32::overflowing_shr`] - * and checked, saturated, and overflowing operations for other primitive types + * [`u32::overflowing_add`], [`u32::overflowing_sub`], + [`u32::overflowing_mul`], [`u32::overflowing_div`] + * [`u32::overflowing_rem`], [`u32::overflowing_neg`], + [`u32::overflowing_shl`], [`u32::overflowing_shr`] + * and checked, saturated, and overflowing operations for other primitive + types * FFI * [`ffi::IntoStringError`] * [`CString::into_string`] @@ -3321,7 +3332,8 @@ Highlights access to all underlying information. * The compiler now contains extended explanations of many errors. When an error with an explanation occurs the compiler suggests using the `--explain` flag - to read the explanation. Error explanations are also [available online][err-index]. + to read the explanation. Error explanations are also + [available online][err-index]. * Thanks to multiple [improvements][sk] to [type checking][pre], as well as other work, the time to bootstrap the compiler decreased by 32%. @@ -4156,7 +4168,8 @@ Version 0.10 (2014-04-03) * Trailing commas are now allowed in argument lists and tuple patterns. * The `do` keyword has been removed, it is now a reserved keyword. * Default type parameters have been implemented, but are feature gated. - * Borrowed variables through captures in closures are now considered soundly. + * Borrowed variables through captures in closures are now considered + soundly. * `extern mod` is now `extern crate` * The `Freeze` trait has been removed. * The `Share` trait has been added for types that can be shared among @@ -4187,8 +4200,8 @@ Version 0.10 (2014-04-03) * std: The `vec` module has been renamed to `slice`. * std: A new vector type, `Vec`, has been added in preparation for DST. This will become the only growable vector in the future. - * std: `std::io` now has more public-reexports. Types such as `BufferedReader` - are now found at `std::io::BufferedReader` instead of + * std: `std::io` now has more public-reexports. Types such as + `BufferedReader` are now found at `std::io::BufferedReader` instead of `std::io::buffered::BufferedReader`. * std: `print` and `println` are no longer in the prelude, the `print!` and `println!` macros are intended to be used instead. @@ -4210,7 +4223,8 @@ Version 0.10 (2014-04-03) can be found on the wiki's style guide. * std: `eof()` has been removed from the `Reader` trait. Specific types may still implement the function. - * std: Networking types are now cloneable to allow simultaneous reads/writes. + * std: Networking types are now cloneable to allow simultaneous + reads/writes. * std: `assert_approx_eq!` has been removed * std: The `e` and `E` formatting specifiers for floats have been added to print them in exponential notation. @@ -4331,24 +4345,25 @@ Version 0.9 (2014-01-09) * Comments may be nested. * Values automatically coerce to trait objects they implement, without an explicit `as`. - * Enum discriminants are no longer an entire word but as small as needed to - contain all the variants. The `repr` attribute can be used to override - the discriminant size, as in `#[repr(int)]` for integer-sized, and - `#[repr(C)]` to match C enums. + * Enum discriminants are no longer an entire word but as small as needed + to contain all the variants. The `repr` attribute can be used to + override the discriminant size, as in `#[repr(int)]` for integer-sized, + and `#[repr(C)]` to match C enums. * Non-string literals are not allowed in attributes (they never worked). * The FFI now supports variadic functions. * Octal numeric literals, as in `0o7777`. - * The `concat!` syntax extension performs compile-time string concatenation. + * The `concat!` syntax extension performs compile-time string + concatenation. * The `#[fixed_stack_segment]` and `#[rust_stack]` attributes have been removed as Rust no longer uses segmented stacks. * Non-ascii identifiers are feature-gated (`#[feature(non_ascii_idents)]`). - * Ignoring all fields of an enum variant or tuple-struct is done with `..`, - not `*`; ignoring remaining fields of a struct is also done with `..`, - not `_`; ignoring a slice of a vector is done with `..`, not `.._`. + * Ignoring all fields of an enum variant or tuple-struct is done with + `..`, not `*`; ignoring remaining fields of a struct is also done with + `..`, not `_`; ignoring a slice of a vector is done with `..`, not `.._`. * `rustc` supports the "win64" calling convention via `extern "win64"`. * `rustc` supports the "system" calling convention, which defaults to the - preferred convention for the target platform, "stdcall" on 32-bit Windows, - "C" elsewhere. + preferred convention for the target platform, "stdcall" on 32-bit + Windows, "C" elsewhere. * The `type_overflow` lint (default: warn) checks literals for overflow. * The `unsafe_block` lint (default: allow) checks for usage of `unsafe`. * The `attribute_usage` lint (default: warn) warns about unknown diff --git a/appveyor.yml b/appveyor.yml index 46ff9a252a0f6..744ef2b2b24e4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -144,10 +144,10 @@ on_failure: - cat %CD%/sccache.log cache: - - "build/i686-pc-windows-msvc/llvm -> src/rustllvm/llvm-auto-clean-trigger" - - "build/x86_64-pc-windows-msvc/llvm -> src/rustllvm/llvm-auto-clean-trigger" - - "i686-pc-windows-msvc/llvm -> src/rustllvm/llvm-auto-clean-trigger" - - "x86_64-pc-windows-msvc/llvm -> src/rustllvm/llvm-auto-clean-trigger" + - "build/i686-pc-windows-msvc/llvm -> src/rustllvm/llvm-rebuild-trigger" + - "build/x86_64-pc-windows-msvc/llvm -> src/rustllvm/llvm-rebuild-trigger" + - "i686-pc-windows-msvc/llvm -> src/rustllvm/llvm-rebuild-trigger" + - "x86_64-pc-windows-msvc/llvm -> src/rustllvm/llvm-rebuild-trigger" branches: only: diff --git a/configure b/configure index 9b34e214214a5..35b376d5f27b8 100755 --- a/configure +++ b/configure @@ -437,6 +437,7 @@ opt local-rust 0 "use an installed rustc rather than downloading a snapshot" opt local-rebuild 0 "assume local-rust matches the current version, for rebuilds; implies local-rust, and is implied if local-rust already matches the current version" opt llvm-static-stdcpp 0 "statically link to libstdc++ for LLVM" opt llvm-link-shared 0 "prefer shared linking to LLVM (llvm-config --link-shared)" +opt llvm-clean-rebuild 0 "delete LLVM build directory on rebuild" opt rpath 1 "build rpaths into rustc itself" opt stage0-landing-pads 1 "enable landing pads during bootstrap with stage0" # This is used by the automation to produce single-target nightlies diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 431d4a333d337..dcd49c51e3a99 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -60,6 +60,7 @@ pub struct Config { pub llvm_link_shared: bool, pub llvm_targets: Option, pub llvm_link_jobs: Option, + pub llvm_clean_rebuild: bool, // rust codegen options pub rust_optimize: bool, @@ -181,6 +182,7 @@ struct Llvm { static_libstdcpp: Option, targets: Option, link_jobs: Option, + clean_rebuild: Option, } #[derive(RustcDecodable, Default, Clone)] @@ -334,6 +336,7 @@ impl Config { set(&mut config.llvm_release_debuginfo, llvm.release_debuginfo); set(&mut config.llvm_version_check, llvm.version_check); set(&mut config.llvm_static_stdcpp, llvm.static_libstdcpp); + set(&mut config.llvm_clean_rebuild, llvm.clean_rebuild); config.llvm_targets = llvm.targets.clone(); config.llvm_link_jobs = llvm.link_jobs; } @@ -439,6 +442,7 @@ impl Config { ("LLVM_VERSION_CHECK", self.llvm_version_check), ("LLVM_STATIC_STDCPP", self.llvm_static_stdcpp), ("LLVM_LINK_SHARED", self.llvm_link_shared), + ("LLVM_CLEAN_REBUILD", self.llvm_clean_rebuild), ("OPTIMIZE", self.rust_optimize), ("DEBUG_ASSERTIONS", self.rust_debug_assertions), ("DEBUGINFO", self.rust_debuginfo), diff --git a/src/bootstrap/config.toml.example b/src/bootstrap/config.toml.example index 776bd729119e2..5a00e90f370b5 100644 --- a/src/bootstrap/config.toml.example +++ b/src/bootstrap/config.toml.example @@ -61,6 +61,11 @@ # controlled by rustbuild's -j parameter. #link-jobs = 0 +# Delete LLVM build directory on LLVM rebuild. +# This option defaults to `false` for local development, but CI may want to +# always perform clean full builds (possibly accelerated by (s)ccache). +#clean-rebuild = false + # ============================================================================= # General build configuration options # ============================================================================= diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 5a5cfe0c682d4..db8ed579cecdb 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -168,9 +168,7 @@ pub fn std(build: &Build, stage: u32, target: &str) { // We don't want to build docs for internal std dependencies unless // in compiler-docs mode. When not in that mode, we whitelist the crates // for which docs must be built. - if build.config.compiler_docs { - cargo.arg("-p").arg("std"); - } else { + if !build.config.compiler_docs { cargo.arg("--no-deps"); for krate in &["alloc", "collections", "core", "std", "std_unicode"] { cargo.arg("-p").arg(krate); @@ -244,9 +242,15 @@ pub fn rustc(build: &Build, stage: u32, target: &str) { .arg(build.src.join("src/rustc/Cargo.toml")) .arg("--features").arg(build.rustc_features()); - // Like with libstd above if compiler docs aren't enabled then we're not - // documenting internal dependencies, so we have a whitelist. - if !build.config.compiler_docs { + if build.config.compiler_docs { + // src/rustc/Cargo.toml contains bin crates called rustc and rustdoc + // which would otherwise overwrite the docs for the real rustc and + // rustdoc lib crates. + cargo.arg("-p").arg("rustc_driver") + .arg("-p").arg("rustdoc"); + } else { + // Like with libstd above if compiler docs aren't enabled then we're not + // documenting internal dependencies, so we have a whitelist. cargo.arg("--no-deps"); for krate in &["proc_macro"] { cargo.arg("-p").arg(krate); diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index c13235b9c7680..6cc1ca8d02ed0 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -41,9 +41,9 @@ pub fn llvm(build: &Build, target: &str) { } } - let clean_trigger = build.src.join("src/rustllvm/llvm-auto-clean-trigger"); - let mut clean_trigger_contents = String::new(); - t!(t!(File::open(&clean_trigger)).read_to_string(&mut clean_trigger_contents)); + let rebuild_trigger = build.src.join("src/rustllvm/llvm-rebuild-trigger"); + let mut rebuild_trigger_contents = String::new(); + t!(t!(File::open(&rebuild_trigger)).read_to_string(&mut rebuild_trigger_contents)); let out_dir = build.llvm_out(target); let done_stamp = out_dir.join("llvm-finished-building"); @@ -51,18 +51,15 @@ pub fn llvm(build: &Build, target: &str) { let mut done_contents = String::new(); t!(t!(File::open(&done_stamp)).read_to_string(&mut done_contents)); - // LLVM was already built previously. - // We don't track changes in LLVM sources, so we need to choose between reusing - // what was built previously, or cleaning the directory and doing a fresh build. - // The choice depends on contents of the clean-trigger file. - // If the contents are the same as during the previous build, then no action is required. - // If the contents differ from the previous build, then cleaning is triggered. - if done_contents == clean_trigger_contents { + // If LLVM was already built previously and contents of the rebuild-trigger file + // didn't change from the previous build, then no action is required. + if done_contents == rebuild_trigger_contents { return - } else { - t!(fs::remove_dir_all(&out_dir)); } } + if build.config.llvm_clean_rebuild { + drop(fs::remove_dir_all(&out_dir)); + } println!("Building LLVM for {}", target); let _time = util::timeit(); @@ -154,7 +151,7 @@ pub fn llvm(build: &Build, target: &str) { // tools and libs on all platforms. cfg.build(); - t!(t!(File::create(&done_stamp)).write_all(clean_trigger_contents.as_bytes())); + t!(t!(File::create(&done_stamp)).write_all(rebuild_trigger_contents.as_bytes())); } fn check_llvm_version(build: &Build, llvm_config: &Path) { diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs index 39f07459d4267..6b047c62d99be 100644 --- a/src/bootstrap/step.rs +++ b/src/bootstrap/step.rs @@ -633,12 +633,16 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { for (krate, path, default) in krates("test") { rules.doc(&krate.doc_step, path) .dep(|s| s.name("libtest-link")) + // Needed so rustdoc generates relative links to std. + .dep(|s| s.name("doc-crate-std")) .default(default && build.config.compiler_docs) .run(move |s| doc::test(build, s.stage, s.target)); } for (krate, path, default) in krates("rustc-main") { rules.doc(&krate.doc_step, path) .dep(|s| s.name("librustc-link")) + // Needed so rustdoc generates relative links to std. + .dep(|s| s.name("doc-crate-std")) .host(true) .default(default && build.config.docs) .run(move |s| doc::rustc(build, s.stage, s.target)); @@ -1213,20 +1217,20 @@ mod tests { name: "std".to_string(), deps: Vec::new(), path: cwd.join("src/std"), - doc_step: "doc-std".to_string(), + doc_step: "doc-crate-std".to_string(), build_step: "build-crate-std".to_string(), - test_step: "test-std".to_string(), - bench_step: "bench-std".to_string(), + test_step: "test-crate-std".to_string(), + bench_step: "bench-crate-std".to_string(), version: String::new(), }); build.crates.insert("test".to_string(), ::Crate { name: "test".to_string(), deps: Vec::new(), path: cwd.join("src/test"), - doc_step: "doc-test".to_string(), + doc_step: "doc-crate-test".to_string(), build_step: "build-crate-test".to_string(), - test_step: "test-test".to_string(), - bench_step: "bench-test".to_string(), + test_step: "test-crate-test".to_string(), + bench_step: "bench-crate-test".to_string(), version: String::new(), }); build.crates.insert("rustc-main".to_string(), ::Crate { @@ -1234,10 +1238,10 @@ mod tests { deps: Vec::new(), version: String::new(), path: cwd.join("src/rustc-main"), - doc_step: "doc-rustc-main".to_string(), + doc_step: "doc-crate-rustc-main".to_string(), build_step: "build-crate-rustc-main".to_string(), - test_step: "test-rustc-main".to_string(), - bench_step: "bench-rustc-main".to_string(), + test_step: "test-crate-rustc-main".to_string(), + bench_step: "bench-crate-rustc-main".to_string(), }); return build } diff --git a/src/ci/run.sh b/src/ci/run.sh index 4c4836d7ca230..19bea9ced0642 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -28,6 +28,7 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-quiet-tests" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-manage-submodules" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-locked-deps" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-cargo-openssl-static" +RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-clean-rebuild" if [ "$DIST_SRC" = "" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-dist-src" diff --git a/src/doc/book/src/strings.md b/src/doc/book/src/strings.md index ffc9d2b697684..416270980bd9c 100644 --- a/src/doc/book/src/strings.md +++ b/src/doc/book/src/strings.md @@ -106,8 +106,8 @@ Usually, access to a vector with `[]` is very fast. But, because each character in a UTF-8 encoded string can be multiple bytes, you have to walk over the string to find the nᵗʰ letter of a string. This is a significantly more expensive operation, and we don’t want to be misleading. Furthermore, ‘letter’ -isn’t something defined in Unicode, exactly. We can choose to look at a string as -individual bytes, or as codepoints: +isn’t something defined in Unicode, exactly. We can choose to look at a string +as individual bytes, or as codepoints: ```rust let hachiko = "忠犬ハチ公"; @@ -163,8 +163,8 @@ let hachi = &dog[0..2]; with this error: ```text -thread 'main' panicked at 'byte index 2 is not a char boundary; it is inside '忠' -(bytes 0..3) of `忠犬ハチ公`' +thread 'main' panicked at 'byte index 2 is not a char boundary; it is inside +'忠' (bytes 0..3) of `忠犬ハチ公`' ``` ## Concatenation diff --git a/src/doc/book/src/traits.md b/src/doc/book/src/traits.md index 19a133f84b0b6..4512ec0f4d9a7 100644 --- a/src/doc/book/src/traits.md +++ b/src/doc/book/src/traits.md @@ -23,7 +23,8 @@ impl Circle { [methodsyntax]: method-syntax.html Traits are similar, except that we first define a trait with a method -signature, then implement the trait for a type. In this example, we implement the trait `HasArea` for `Circle`: +signature, then implement the trait for a type. In this example, we implement +the trait `HasArea` for `Circle`: ```rust struct Circle { @@ -78,8 +79,8 @@ impl HasArea for Circle { ## Trait bounds on generic functions Traits are useful because they allow a type to make certain promises about its -behavior. Generic functions can exploit this to constrain, or [bound][bounds], the types they -accept. Consider this function, which does not compile: +behavior. Generic functions can exploit this to constrain, or [bound][bounds], +the types they accept. Consider this function, which does not compile: [bounds]: glossary.html#bounds @@ -427,13 +428,16 @@ fn inverse(x: i32) -> T ``` This shows off the additional feature of `where` clauses: they allow bounds -on the left-hand side not only of type parameters `T`, but also of types (`i32` in this case). In this example, `i32` must implement +on the left-hand side not only of type parameters `T`, but also of types +(`i32` in this case). In this example, `i32` must implement `ConvertTo`. Rather than defining what `i32` is (since that's obvious), the `where` clause here constrains `T`. # Default methods -A default method can be added to a trait definition if it is already known how a typical implementor will define a method. For example, `is_invalid()` is defined as the opposite of `is_valid()`: +A default method can be added to a trait definition if it is already known how +a typical implementor will define a method. For example, `is_invalid()` is +defined as the opposite of `is_valid()`: ```rust trait Foo { @@ -443,7 +447,9 @@ trait Foo { } ``` -Implementors of the `Foo` trait need to implement `is_valid()` but not `is_invalid()` due to the added default behavior. This default behavior can still be overridden as in: +Implementors of the `Foo` trait need to implement `is_valid()` but not +`is_invalid()` due to the added default behavior. This default behavior can +still be overridden as in: ```rust # trait Foo { diff --git a/src/doc/book/src/unsized-types.md b/src/doc/book/src/unsized-types.md index 2d090925d51f6..7599be067bace 100644 --- a/src/doc/book/src/unsized-types.md +++ b/src/doc/book/src/unsized-types.md @@ -2,9 +2,9 @@ Most types have a particular size, in bytes, that is knowable at compile time. For example, an `i32` is thirty-two bits big, or four bytes. However, there are -some types which are useful to express, but do not have a defined size. These are -called ‘unsized’ or ‘dynamically sized’ types. One example is `[T]`. This type -represents a certain number of `T` in sequence. But we don’t know how many +some types which are useful to express, but do not have a defined size. These +are called ‘unsized’ or ‘dynamically sized’ types. One example is `[T]`. This +type represents a certain number of `T` in sequence. But we don’t know how many there are, so the size is not known. Rust understands a few of these types, but they have some restrictions. There diff --git a/src/doc/book/src/variable-bindings.md b/src/doc/book/src/variable-bindings.md index d6aa8b1acb72f..d5b40cddd71bb 100644 --- a/src/doc/book/src/variable-bindings.md +++ b/src/doc/book/src/variable-bindings.md @@ -241,10 +241,10 @@ println!("{}", x); // Prints "42". Shadowing and mutable bindings may appear as two sides of the same coin, but they are two distinct concepts that can't always be used interchangeably. For one, shadowing enables us to rebind a name to a value of a different type. It -is also possible to change the mutability of a binding. Note that shadowing a +is also possible to change the mutability of a binding. Note that shadowing a name does not alter or destroy the value it was bound to, and the value will -continue to exist until it goes out of scope, even if it is no longer accessible -by any means. +continue to exist until it goes out of scope, even if it is no longer +accessible by any means. ```rust let mut x: i32 = 1; diff --git a/src/doc/book/src/vectors.md b/src/doc/book/src/vectors.md index aff078718dfb1..af1e729ab507d 100644 --- a/src/doc/book/src/vectors.md +++ b/src/doc/book/src/vectors.md @@ -115,9 +115,10 @@ for i in v { } ``` -Note: You cannot use the vector again once you have iterated by taking ownership of the vector. -You can iterate the vector multiple times by taking a reference to the vector whilst iterating. -For example, the following code does not compile. +Note: You cannot use the vector again once you have iterated by taking +ownership of the vector. You can iterate the vector multiple times by taking a +reference to the vector whilst iterating. For example, the following code does +not compile. ```rust,ignore let v = vec![1, 2, 3, 4, 5]; diff --git a/src/doc/grammar.md b/src/doc/grammar.md index 8e803aff4d6fe..36b28fd253767 100644 --- a/src/doc/grammar.md +++ b/src/doc/grammar.md @@ -2,8 +2,8 @@ # Introduction -This document is the primary reference for the Rust programming language grammar. It -provides only one kind of material: +This document is the primary reference for the Rust programming language +grammar. It provides only one kind of material: - Chapters that formally define the language grammar. @@ -90,8 +90,8 @@ codepoints, but a small number are defined in terms of Unicode properties or explicit codepoint lists. [^inputformat] [^inputformat]: Substitute definitions for the special Unicode productions are - provided to the grammar verifier, restricted to ASCII range, when verifying the - grammar in this document. + provided to the grammar verifier, restricted to ASCII range, when verifying + the grammar in this document. ## Special Unicode Productions @@ -710,7 +710,8 @@ return_expr : "return" expr ? ; # Type system -**FIXME:** is this entire chapter relevant here? Or should it all have been covered by some production already? +**FIXME:** is this entire chapter relevant here? Or should it all have been +covered by some production already? ## Types @@ -790,7 +791,8 @@ never_type : "!" ; # Memory and concurrency models -**FIXME:** is this entire chapter relevant here? Or should it all have been covered by some production already? +**FIXME:** is this entire chapter relevant here? Or should it all have been +covered by some production already? ## Memory model diff --git a/src/doc/index.md b/src/doc/index.md index 1f262b360e3ed..b113e8510d60f 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -30,7 +30,8 @@ nicknamed 'The Rust Bookshelf.' * [The Rust Programming Language][book] teaches you how to program in Rust. * [The Unstable Book][unstable-book] has documentation for unstable features. * [The Rustonomicon][nomicon] is your guidebook to the dark arts of unsafe Rust. -* [The Reference][ref] is not a formal spec, but is more detailed and comprehensive than the book. +* [The Reference][ref] is not a formal spec, but is more detailed and + comprehensive than the book. Another few words about the reference: it is guaranteed to be accurate, but not complete. We now have a policy that all new features must be included in the diff --git a/src/doc/intro.md b/src/doc/intro.md index 48712d8d49b55..6e39e67061d1d 100644 --- a/src/doc/intro.md +++ b/src/doc/intro.md @@ -1,5 +1,6 @@ % A 30-minute Introduction to Rust -This introduction is now deprecated. Please see [the introduction to the book][intro]. +This introduction is now deprecated. Please see +[the introduction to the book][intro]. [intro]: book/README.html diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index d9b8c5ea589fd..df4aef088712c 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -336,7 +336,7 @@ mod range; mod sources; mod traits; -/// An double-ended iterator with the direction inverted. +/// A double-ended iterator with the direction inverted. /// /// This `struct` is created by the [`rev()`] method on [`Iterator`]. See its /// documentation for more. diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 34d8c6500b926..9d40419d338b8 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -833,8 +833,21 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { self.trans_lvalue(bcx, dest) }; if fn_ret_ty.is_indirect() { - llargs.push(dest.llval); - ReturnDest::Nothing + match dest.alignment { + Alignment::AbiAligned => { + llargs.push(dest.llval); + ReturnDest::Nothing + }, + Alignment::Packed => { + // Currently, MIR code generation does not create calls + // that store directly to fields of packed structs (in + // fact, the calls it creates write only to temps), + // + // If someone changes that, please update this code path + // to create a temporary. + span_bug!(self.mir.span, "can't directly store to unaligned value"); + } + } } else { ReturnDest::Store(dest.llval) } diff --git a/src/librustc_trans/mir/operand.rs b/src/librustc_trans/mir/operand.rs index cb77fcbbff85d..3f29545ecf45a 100644 --- a/src/librustc_trans/mir/operand.rs +++ b/src/librustc_trans/mir/operand.rs @@ -268,10 +268,17 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { bcx.store(base::from_immediate(bcx, s), lldest, align); } OperandValue::Pair(a, b) => { + let f_align = match *bcx.ccx.layout_of(operand.ty) { + Layout::Univariant { ref variant, .. } if variant.packed => { + Some(1) + } + _ => align + }; + let a = base::from_immediate(bcx, a); let b = base::from_immediate(bcx, b); - bcx.store(a, bcx.struct_gep(lldest, 0), align); - bcx.store(b, bcx.struct_gep(lldest, 1), align); + bcx.store(a, bcx.struct_gep(lldest, 0), f_align); + bcx.store(b, bcx.struct_gep(lldest, 1), f_align); } } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 44f71d8952985..c571bcb08e4b7 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -763,7 +763,7 @@ fn write_shared(cx: &Context, // going on). If they're in different crates then the crate defining // the trait will be interested in our implementation. if imp.def_id.krate == did.krate { continue } - write!(implementors, r#""{}","#, imp.impl_).unwrap(); + write!(implementors, "{},", as_json(&imp.impl_.to_string())).unwrap(); } implementors.push_str("];"); diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-rebuild-trigger similarity index 66% rename from src/rustllvm/llvm-auto-clean-trigger rename to src/rustllvm/llvm-rebuild-trigger index e30ad63d52f87..aeabf4a1dd376 100644 --- a/src/rustllvm/llvm-auto-clean-trigger +++ b/src/rustllvm/llvm-rebuild-trigger @@ -1,4 +1,4 @@ -# If this file is modified, then llvm will be forcibly cleaned and then rebuilt. +# If this file is modified, then llvm will be (optionally) cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. 2017-03-04 diff --git a/src/stage0.txt b/src/stage0.txt index 772029ab0c253..4b6d6312c8b14 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -1,4 +1,4 @@ -# This file describes the stage0 compiler that's used to then bootstrap the Rust +# This file describes the stage0 compiler that's used to bootstrap the Rust # compiler itself. For the rustbuild build system, this also describes the # relevant Cargo revision that we're using. # diff --git a/src/test/codegen/packed.rs b/src/test/codegen/packed.rs index db2cd3b41656d..99e6e38a3bf0b 100644 --- a/src/test/codegen/packed.rs +++ b/src/test/codegen/packed.rs @@ -27,3 +27,36 @@ pub fn write_pkd(pkd: &mut Packed) -> u32 { pkd.data = 42; result } + +pub struct Array([i32; 8]); +#[repr(packed)] +pub struct BigPacked { + dealign: u8, + data: Array +} + +// CHECK-LABEL: @call_pkd +#[no_mangle] +pub fn call_pkd(f: fn() -> Array) -> BigPacked { +// CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array +// CHECK: call void %{{.*}}(%Array* noalias nocapture sret dereferenceable(32) [[ALLOCA]]) +// CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* %{{.*}}, i{{[0-9]+}} 32, i32 1, i1 false) + // check that calls whose destination is a field of a packed struct + // go through an alloca rather than calling the function with an + // unaligned destination. + BigPacked { dealign: 0, data: f() } +} + +#[repr(packed)] +#[derive(Copy, Clone)] +pub struct PackedPair(u8, u32); + +// CHECK-LABEL: @pkd_pair +#[no_mangle] +pub fn pkd_pair(pair1: &mut PackedPair, pair2: &mut PackedPair) { + // CHECK: [[V1:%[a-z0-9]+]] = load i8, i8* %{{.*}}, align 1 + // CHECK: [[V2:%[a-z0-9]+]] = load i32, i32* %{{.*}}, align 1 + // CHECK: store i8 [[V1]], i8* {{.*}}, align 1 + // CHECK: store i32 [[V2]], i32* {{.*}}, align 1 + *pair2 = *pair1; +}