From f4c59b37ec194d0f7882196dc51aa5ea098e7b18 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 25 Oct 2019 18:11:20 +0200 Subject: [PATCH 01/35] Use `drop_in_place` in `array::IntoIter::drop` This skips the loop when the element type is known not to have drop glue, even in debug mode. --- src/libcore/array/iter.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/libcore/array/iter.rs b/src/libcore/array/iter.rs index 850a599c6599f..ba1fd83ae4f2d 100644 --- a/src/libcore/array/iter.rs +++ b/src/libcore/array/iter.rs @@ -92,6 +92,15 @@ where mem::transmute::<&[MaybeUninit], &[T]>(slice) } } + + /// Returns a mutable slice of all elements that have not been yielded yet. + fn as_mut_slice(&mut self) -> &mut [T] { + // This transmute is safe, same as in `as_slice` above. + let slice = &mut self.data[self.alive.clone()]; + unsafe { + mem::transmute::<&mut [MaybeUninit], &mut [T]>(slice) + } + } } @@ -182,10 +191,9 @@ where [T; N]: LengthAtMost32, { fn drop(&mut self) { - // We simply drop each element via `for_each`. This should not incur - // any significant runtime overhead and avoids adding another `unsafe` - // block. - self.by_ref().for_each(drop); + unsafe { + ptr::drop_in_place(self.as_mut_slice()) + } } } From 7550b618f9489f7e7f7c4659beef6f0070ad8b19 Mon Sep 17 00:00:00 2001 From: Artur Kovacs Date: Mon, 4 Nov 2019 19:37:37 +0100 Subject: [PATCH 02/35] Fix documentation for `Iterator::count()`. --- src/libcore/iter/traits/iterator.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index 7ffc8b3729cb4..90535a647ccca 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -202,8 +202,9 @@ pub trait Iterator { /// Consumes the iterator, counting the number of iterations and returning it. /// /// This method will evaluate the iterator until its [`next`] returns - /// [`None`]. Once [`None`] is encountered, `count()` returns the number of - /// times it called [`next`]. + /// [`None`]. Once [`None`] is encountered, `count()` returns one less than the + /// number of times it called [`next`]. Note that [`next`] has to be called at + /// least once even if the iterator does not have any elements. /// /// [`next`]: #tymethod.next /// [`None`]: ../../std/option/enum.Option.html#variant.None From 6ce3e1df478cf4f865f4aa5d7a55bae2d87e5871 Mon Sep 17 00:00:00 2001 From: Artur Kovacs Date: Mon, 4 Nov 2019 20:37:39 +0100 Subject: [PATCH 03/35] Fixed trailing whitespace. --- src/libcore/iter/traits/iterator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index 90535a647ccca..e9bbe330208c1 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -202,7 +202,7 @@ pub trait Iterator { /// Consumes the iterator, counting the number of iterations and returning it. /// /// This method will evaluate the iterator until its [`next`] returns - /// [`None`]. Once [`None`] is encountered, `count()` returns one less than the + /// [`None`]. Once [`None`] is encountered, `count()` returns one less than the /// number of times it called [`next`]. Note that [`next`] has to be called at /// least once even if the iterator does not have any elements. /// From 23be25c82f517cb9ee5c4df57378e024d3c5b3eb Mon Sep 17 00:00:00 2001 From: Artur Kovacs Date: Mon, 4 Nov 2019 22:11:52 +0100 Subject: [PATCH 04/35] Improve wording in the documentation of `Iterator::count()`. --- src/libcore/iter/traits/iterator.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index e9bbe330208c1..b7a35568e3fc5 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -201,13 +201,13 @@ pub trait Iterator { /// Consumes the iterator, counting the number of iterations and returning it. /// - /// This method will evaluate the iterator until its [`next`] returns - /// [`None`]. Once [`None`] is encountered, `count()` returns one less than the - /// number of times it called [`next`]. Note that [`next`] has to be called at - /// least once even if the iterator does not have any elements. + /// This method will call [`next`] repeatedly until [`None`] is encountered, + /// returning the number of times it saw [`Some`]. Note that [`next`] has to be + /// called at least once even if the iterator does not have any elements. /// /// [`next`]: #tymethod.next /// [`None`]: ../../std/option/enum.Option.html#variant.None + /// [`Some`]: ../../std/option/enum.Option.html#variant.Some /// /// # Overflow Behavior /// From 0282c27781b2f7501f4385ef22da82acc179c00e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 6 Nov 2019 18:32:51 +0100 Subject: [PATCH 05/35] rename cfg(rustdoc) into cfg(doc) --- src/bootstrap/bin/rustdoc.rs | 2 +- src/doc/rustdoc/src/unstable-features.md | 8 ++--- .../src/language-features/doc-cfg.md | 4 +-- src/librustdoc/core.rs | 2 +- src/librustdoc/test.rs | 2 +- src/libstd/os/mod.rs | 2 +- src/libstd/sys/mod.rs | 4 +-- src/libstd/sys/unix/mod.rs | 30 +++++++++---------- src/libstd/sys_common/mod.rs | 2 +- src/libsyntax/feature_gate/builtin_attrs.rs | 2 +- .../rustdoc-ui/doc-test-rustdoc-feature.rs | 6 ++-- .../feature-gate-doc_cfg-cfg-rustdoc.rs | 2 +- .../feature-gate-doc_cfg-cfg-rustdoc.stderr | 6 ++-- 13 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index a13ff69a7b56f..6937fb922de48 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -25,7 +25,7 @@ fn main() { let mut dylib_path = bootstrap::util::dylib_path(); dylib_path.insert(0, PathBuf::from(libdir.clone())); - //FIXME(misdreavus): once stdsimd uses cfg(rustdoc) instead of cfg(dox), remove the `--cfg dox` + //FIXME(misdreavus): once stdsimd uses cfg(doc) instead of cfg(dox), remove the `--cfg dox` //arguments here let mut cmd = Command::new(rustdoc); cmd.args(&args) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 3c3e72aa37959..f8be04a1087bf 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -106,11 +106,11 @@ item, it will be accompanied by a banner explaining that the item is only availa platforms. For Rustdoc to document an item, it needs to see it, regardless of what platform it's currently -running on. To aid this, Rustdoc sets the flag `#[cfg(rustdoc)]` when running on your crate. +running on. To aid this, Rustdoc sets the flag `#[cfg(doc)]` when running on your crate. Combining this with the target platform of a given item allows it to appear when building your crate normally on that platform, as well as when building documentation anywhere. -For example, `#[cfg(any(windows, rustdoc))]` will preserve the item either on Windows or during the +For example, `#[cfg(any(windows, doc))]` will preserve the item either on Windows or during the documentation process. Then, adding a new attribute `#[doc(cfg(windows))]` will tell Rustdoc that the item is supposed to be used on Windows. For example: @@ -118,12 +118,12 @@ the item is supposed to be used on Windows. For example: #![feature(doc_cfg)] /// Token struct that can only be used on Windows. -#[cfg(any(windows, rustdoc))] +#[cfg(any(windows, doc))] #[doc(cfg(windows))] pub struct WindowsToken; /// Token struct that can only be used on Unix. -#[cfg(any(unix, rustdoc))] +#[cfg(any(unix, doc))] #[doc(cfg(unix))] pub struct UnixToken; ``` diff --git a/src/doc/unstable-book/src/language-features/doc-cfg.md b/src/doc/unstable-book/src/language-features/doc-cfg.md index 96c66a1515ed5..e75f1aea99229 100644 --- a/src/doc/unstable-book/src/language-features/doc-cfg.md +++ b/src/doc/unstable-book/src/language-features/doc-cfg.md @@ -13,7 +13,7 @@ This attribute has two effects: 2. The item's doc-tests will only run on the specific platform. In addition to allowing the use of the `#[doc(cfg)]` attribute, this feature enables the use of a -special conditional compilation flag, `#[cfg(rustdoc)]`, set whenever building documentation on your +special conditional compilation flag, `#[cfg(doc)]`, set whenever building documentation on your crate. This feature was introduced as part of PR [#43348] to allow the platform-specific parts of the @@ -22,7 +22,7 @@ standard library be documented. ```rust #![feature(doc_cfg)] -#[cfg(any(windows, rustdoc))] +#[cfg(any(windows, doc))] #[doc(cfg(windows))] /// The application's icon in the notification area (a.k.a. system tray). /// diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index b227f432a4e98..c1e3f006ba5c0 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -247,7 +247,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt } = options; // Add the rustdoc cfg into the doc build. - cfgs.push("rustdoc".to_string()); + cfgs.push("doc".to_string()); let cpath = Some(input.clone()); let input = Input::File(input); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 07dc1e4e9157a..5e5e2055a8527 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -63,7 +63,7 @@ pub fn run(options: Options) -> i32 { }; let mut cfgs = options.cfgs.clone(); - cfgs.push("rustdoc".to_owned()); + cfgs.push("doc".to_owned()); cfgs.push("doctest".to_owned()); let config = interface::Config { opts: sessopts, diff --git a/src/libstd/os/mod.rs b/src/libstd/os/mod.rs index d44c8ca544e80..a8d2b0cb397ab 100644 --- a/src/libstd/os/mod.rs +++ b/src/libstd/os/mod.rs @@ -4,7 +4,7 @@ #![allow(missing_docs, nonstandard_style, missing_debug_implementations)] cfg_if::cfg_if! { - if #[cfg(rustdoc)] { + if #[cfg(doc)] { // When documenting libstd we want to show unix/windows/linux modules as // these are the "main modules" that are used across platforms. This diff --git a/src/libstd/sys/mod.rs b/src/libstd/sys/mod.rs index 16b0539cdb9f9..9eeab34643f93 100644 --- a/src/libstd/sys/mod.rs +++ b/src/libstd/sys/mod.rs @@ -56,7 +56,7 @@ cfg_if::cfg_if! { // then later used in the `std::os` module when documenting, for example, // Windows when we're compiling for Linux. -#[cfg(rustdoc)] +#[cfg(doc)] cfg_if::cfg_if! { if #[cfg(unix)] { // On unix we'll document what's already available @@ -80,7 +80,7 @@ cfg_if::cfg_if! { } } -#[cfg(rustdoc)] +#[cfg(doc)] cfg_if::cfg_if! { if #[cfg(windows)] { // On windows we'll just be documenting what's already available diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index d0bed0f038e6c..bf0166ceb6fbf 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -2,21 +2,21 @@ use crate::io::ErrorKind; -#[cfg(any(rustdoc, target_os = "linux"))] pub use crate::os::linux as platform; - -#[cfg(all(not(rustdoc), target_os = "android"))] pub use crate::os::android as platform; -#[cfg(all(not(rustdoc), target_os = "dragonfly"))] pub use crate::os::dragonfly as platform; -#[cfg(all(not(rustdoc), target_os = "freebsd"))] pub use crate::os::freebsd as platform; -#[cfg(all(not(rustdoc), target_os = "haiku"))] pub use crate::os::haiku as platform; -#[cfg(all(not(rustdoc), target_os = "ios"))] pub use crate::os::ios as platform; -#[cfg(all(not(rustdoc), target_os = "macos"))] pub use crate::os::macos as platform; -#[cfg(all(not(rustdoc), target_os = "netbsd"))] pub use crate::os::netbsd as platform; -#[cfg(all(not(rustdoc), target_os = "openbsd"))] pub use crate::os::openbsd as platform; -#[cfg(all(not(rustdoc), target_os = "solaris"))] pub use crate::os::solaris as platform; -#[cfg(all(not(rustdoc), target_os = "emscripten"))] pub use crate::os::emscripten as platform; -#[cfg(all(not(rustdoc), target_os = "fuchsia"))] pub use crate::os::fuchsia as platform; -#[cfg(all(not(rustdoc), target_os = "l4re"))] pub use crate::os::linux as platform; -#[cfg(all(not(rustdoc), target_os = "redox"))] pub use crate::os::redox as platform; +#[cfg(any(doc, target_os = "linux"))] pub use crate::os::linux as platform; + +#[cfg(all(not(doc), target_os = "android"))] pub use crate::os::android as platform; +#[cfg(all(not(doc), target_os = "dragonfly"))] pub use crate::os::dragonfly as platform; +#[cfg(all(not(doc), target_os = "freebsd"))] pub use crate::os::freebsd as platform; +#[cfg(all(not(doc), target_os = "haiku"))] pub use crate::os::haiku as platform; +#[cfg(all(not(doc), target_os = "ios"))] pub use crate::os::ios as platform; +#[cfg(all(not(doc), target_os = "macos"))] pub use crate::os::macos as platform; +#[cfg(all(not(doc), target_os = "netbsd"))] pub use crate::os::netbsd as platform; +#[cfg(all(not(doc), target_os = "openbsd"))] pub use crate::os::openbsd as platform; +#[cfg(all(not(doc), target_os = "solaris"))] pub use crate::os::solaris as platform; +#[cfg(all(not(doc), target_os = "emscripten"))] pub use crate::os::emscripten as platform; +#[cfg(all(not(doc), target_os = "fuchsia"))] pub use crate::os::fuchsia as platform; +#[cfg(all(not(doc), target_os = "l4re"))] pub use crate::os::linux as platform; +#[cfg(all(not(doc), target_os = "redox"))] pub use crate::os::redox as platform; pub use self::rand::hashmap_random_keys; pub use libc::strlen; diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs index 7a0bcd03d758f..8912aed925580 100644 --- a/src/libstd/sys_common/mod.rs +++ b/src/libstd/sys_common/mod.rs @@ -45,7 +45,7 @@ pub mod backtrace; pub mod condvar; pub mod io; pub mod mutex; -#[cfg(any(rustdoc, // see `mod os`, docs are generated for multiple platforms +#[cfg(any(doc, // see `mod os`, docs are generated for multiple platforms unix, target_os = "redox", target_os = "cloudabi", diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs index eb811c3e0ff9b..5370bf2ea2228 100644 --- a/src/libsyntax/feature_gate/builtin_attrs.rs +++ b/src/libsyntax/feature_gate/builtin_attrs.rs @@ -30,7 +30,7 @@ const GATED_CFGS: &[(Symbol, Symbol, GateFn)] = &[ (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)), (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)), (sym::target_has_atomic_load_store, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)), - (sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)), + (sym::doc, sym::doc_cfg, cfg_fn!(doc_cfg)), ]; #[derive(Debug)] diff --git a/src/test/rustdoc-ui/doc-test-rustdoc-feature.rs b/src/test/rustdoc-ui/doc-test-rustdoc-feature.rs index d0ead4136575f..62fd3da9233fa 100644 --- a/src/test/rustdoc-ui/doc-test-rustdoc-feature.rs +++ b/src/test/rustdoc-ui/doc-test-rustdoc-feature.rs @@ -4,11 +4,11 @@ #![feature(doc_cfg)] -// Make sure `cfg(rustdoc)` is set when finding doctests but not inside the doctests. +// Make sure `cfg(doc)` is set when finding doctests but not inside the doctests. /// ``` /// #![feature(doc_cfg)] -/// assert!(!cfg!(rustdoc)); +/// assert!(!cfg!(doc)); /// ``` -#[cfg(rustdoc)] +#[cfg(doc)] pub struct Foo; diff --git a/src/test/ui/feature-gates/feature-gate-doc_cfg-cfg-rustdoc.rs b/src/test/ui/feature-gates/feature-gate-doc_cfg-cfg-rustdoc.rs index 17ea58231915d..9830503a8cac6 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_cfg-cfg-rustdoc.rs +++ b/src/test/ui/feature-gates/feature-gate-doc_cfg-cfg-rustdoc.rs @@ -1,4 +1,4 @@ -#[cfg(rustdoc)] //~ ERROR: `cfg(rustdoc)` is experimental and subject to change +#[cfg(doc)] //~ ERROR: `cfg(doc)` is experimental and subject to change pub struct SomeStruct; fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-doc_cfg-cfg-rustdoc.stderr b/src/test/ui/feature-gates/feature-gate-doc_cfg-cfg-rustdoc.stderr index 9bf97a4a4771c..26a1f4decf4cf 100644 --- a/src/test/ui/feature-gates/feature-gate-doc_cfg-cfg-rustdoc.stderr +++ b/src/test/ui/feature-gates/feature-gate-doc_cfg-cfg-rustdoc.stderr @@ -1,8 +1,8 @@ -error[E0658]: `cfg(rustdoc)` is experimental and subject to change +error[E0658]: `cfg(doc)` is experimental and subject to change --> $DIR/feature-gate-doc_cfg-cfg-rustdoc.rs:1:7 | -LL | #[cfg(rustdoc)] - | ^^^^^^^ +LL | #[cfg(doc)] + | ^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/43781 = help: add `#![feature(doc_cfg)]` to the crate attributes to enable From b7c0e464d5fbe6fdd008c3c25f835e4978a5ae2d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 7 Nov 2019 13:01:53 +0100 Subject: [PATCH 06/35] Add long error explanation for E0623 --- src/librustc/error_codes.rs | 44 ++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index f5ff92e69bc7a..9274608bc2f84 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -1896,6 +1896,49 @@ fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { ``` "##, +E0623: r##" +A lifetime didn't match what was expected. + +Erroneous code example: + +```compile_fail,E0623 +struct Foo<'a> { + x: &'a isize, +} + +fn bar<'short, 'long>(c: Foo<'short>, l: &'long isize) { + let _: Foo<'long> = c; // error! +} +``` + +In this example, we tried to set a value with an incompatible lifetime to +another one (`'long` != `'short`). We can solve this issue in two different +ways: either we make `'short` lives longer than `'long`: + +``` +struct Foo<'a> { + x: &'a isize, +} + +// we set 'short to outlive 'long +fn bar<'short: 'long, 'long>(c: Foo<'short>, l: &'long isize) { + let _: Foo<'long> = c; // ok! +} +``` + +Or we use only one lifetime: + +``` +struct Foo<'a> { + x: &'a isize, +} + +fn bar<'short>(c: Foo<'short>, l: &'short isize) { + let _: Foo<'short> = c; // ok! +} +``` +"##, + E0635: r##" The `#![feature]` attribute specified an unknown feature. @@ -2329,7 +2372,6 @@ the future, [RFC 2091] prohibits their implementation without a follow-up RFC. E0488, // lifetime of variable does not enclose its declaration E0489, // type/lifetime parameter not in scope here E0490, // a value of type `..` is borrowed for too long - E0623, // lifetime mismatch where both parameters are anonymous regions E0628, // generators cannot have explicit parameters E0631, // type mismatch in closure arguments E0637, // "'_" is not a valid lifetime bound From ffc1c5a04d431679a6b6c5c92fdd7ad77b109c98 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 7 Nov 2019 13:02:34 +0100 Subject: [PATCH 07/35] Update ui tests --- .../associated-type-bounds/implied-region-constraints.stderr | 1 + .../associated-types-project-from-hrtb-in-fn-body.stderr | 1 + .../ui/associated-types/associated-types-subtyping-1.stderr | 1 + .../cache/project-fn-ret-contravariant.krisskross.stderr | 1 + .../cache/project-fn-ret-invariant.krisskross.stderr | 1 + .../cache/project-fn-ret-invariant.oneuse.stderr | 1 + src/test/ui/async-await/issues/issue-63388-1.stderr | 1 + .../async-await/multiple-lifetimes/ret-impl-trait-one.stderr | 1 + .../borrowck-reborrow-from-shorter-lived-andmut.stderr | 1 + src/test/ui/continue-after-missing-main.stderr | 3 ++- .../ui/impl-trait/must_outlive_least_region_or_bound.stderr | 3 ++- src/test/ui/in-band-lifetimes/mismatched.stderr | 3 ++- src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr | 1 + src/test/ui/issues/issue-17728.stderr | 3 ++- .../ex1-return-one-existing-name-if-else-using-impl.stderr | 1 + .../ex1-return-one-existing-name-return-type-is-anon.stderr | 1 + .../ex1-return-one-existing-name-self-is-anon.stderr | 1 + .../lifetime-errors/ex2b-push-no-existing-names.stderr | 1 + .../lifetime-errors/ex2c-push-inference-variable.stderr | 1 + .../lifetime-errors/ex2d-push-inference-variable-2.stderr | 1 + .../lifetime-errors/ex2e-push-inference-variable-3.stderr | 1 + .../lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr | 1 + .../lifetimes/lifetime-errors/ex3-both-anon-regions-3.stderr | 1 + .../ex3-both-anon-regions-both-are-structs-2.stderr | 1 + .../ex3-both-anon-regions-both-are-structs-3.stderr | 1 + ...oth-anon-regions-both-are-structs-earlybound-regions.stderr | 1 + ...both-anon-regions-both-are-structs-latebound-regions.stderr | 1 + .../ex3-both-anon-regions-both-are-structs.stderr | 1 + .../ex3-both-anon-regions-latebound-regions.stderr | 1 + .../ex3-both-anon-regions-one-is-struct-2.stderr | 1 + .../ex3-both-anon-regions-one-is-struct-3.stderr | 1 + .../ex3-both-anon-regions-one-is-struct-4.stderr | 1 + .../lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr | 1 + .../ex3-both-anon-regions-return-type-is-anon.stderr | 1 + .../lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr | 1 + .../ex3-both-anon-regions-using-fn-items.stderr | 1 + .../ex3-both-anon-regions-using-impl-items.stderr | 1 + .../ex3-both-anon-regions-using-trait-objects.stderr | 1 + .../ui/lifetimes/lifetime-errors/ex3-both-anon-regions.stderr | 1 + .../ui/object-lifetime/object-lifetime-default-mybox.stderr | 3 ++- .../regions/region-lifetime-bounds-on-fns-where-clause.stderr | 3 ++- .../region-multiple-lifetime-bounds-on-fns-where-clause.stderr | 3 ++- .../regions-bounded-method-type-parameters-cross-crate.stderr | 1 + .../regions-bounded-method-type-parameters-trait-bound.stderr | 1 + src/test/ui/regions/regions-creating-enums3.stderr | 1 + src/test/ui/regions/regions-free-region-ordering-callee.stderr | 1 + .../regions/regions-free-region-ordering-caller.migrate.stderr | 1 + .../ui/regions/regions-infer-contravariance-due-to-decl.stderr | 1 + .../ui/regions/regions-infer-covariance-due-to-decl.stderr | 1 + src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr | 3 ++- .../regions-reborrow-from-shorter-mut-ref-mut-ref.stderr | 1 + .../ui/regions/regions-reborrow-from-shorter-mut-ref.stderr | 1 + ...iance-contravariant-use-covariant-in-second-position.stderr | 1 + .../regions-variance-contravariant-use-covariant.stderr | 1 + .../regions-variance-covariant-use-contravariant.stderr | 1 + .../regions-variance-invariant-use-contravariant.stderr | 1 + .../arbitrary_self_types_pin_lifetime_mismatch-async.stderr | 1 + .../ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr | 1 + src/test/ui/self/elision/lt-ref-self-async.stderr | 1 + src/test/ui/self/elision/lt-ref-self.stderr | 1 + src/test/ui/self/elision/ref-mut-self-async.stderr | 1 + src/test/ui/self/elision/ref-mut-self.stderr | 1 + src/test/ui/self/elision/ref-mut-struct-async.stderr | 1 + src/test/ui/self/elision/ref-mut-struct.stderr | 1 + src/test/ui/self/elision/ref-self-async.stderr | 1 + src/test/ui/self/elision/ref-self.stderr | 1 + src/test/ui/self/elision/ref-struct-async.stderr | 1 + src/test/ui/self/elision/ref-struct.stderr | 1 + .../underscore-lifetime-elison-mismatch.stderr | 1 + src/test/ui/variance/variance-cell-is-invariant.stderr | 1 + 70 files changed, 78 insertions(+), 8 deletions(-) diff --git a/src/test/ui/associated-type-bounds/implied-region-constraints.stderr b/src/test/ui/associated-type-bounds/implied-region-constraints.stderr index 9968f3e8bac5e..60c6e8a80fb6a 100644 --- a/src/test/ui/associated-type-bounds/implied-region-constraints.stderr +++ b/src/test/ui/associated-type-bounds/implied-region-constraints.stderr @@ -18,3 +18,4 @@ LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x; error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.stderr b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.stderr index 63d662f44658a..d5310c47fcf1e 100644 --- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.stderr +++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.stderr @@ -11,3 +11,4 @@ LL | let z: I::A = if cond { x } else { y }; error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/associated-types/associated-types-subtyping-1.stderr b/src/test/ui/associated-types/associated-types-subtyping-1.stderr index 660e5b3928acf..58ceec9040b9d 100644 --- a/src/test/ui/associated-types/associated-types-subtyping-1.stderr +++ b/src/test/ui/associated-types/associated-types-subtyping-1.stderr @@ -18,3 +18,4 @@ LL | let _c: >::Type = b; error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.stderr b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.stderr index dc9a549586bab..fa4c6adb5fff7 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.stderr @@ -22,3 +22,4 @@ LL | (a, b) error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr index 6accf8110ad1e..5009e0868a7d4 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr @@ -21,3 +21,4 @@ LL | let b = bar(foo, x); error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr index ef036bd8fbaa8..65d16440ac9b0 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr @@ -11,3 +11,4 @@ LL | let b = bar(f, y); error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/async-await/issues/issue-63388-1.stderr b/src/test/ui/async-await/issues/issue-63388-1.stderr index 2917fa9ccb7f2..8813183312ddf 100644 --- a/src/test/ui/async-await/issues/issue-63388-1.stderr +++ b/src/test/ui/async-await/issues/issue-63388-1.stderr @@ -11,3 +11,4 @@ LL | foo error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr index f6d611517bc8f..7b8f290d6c2f8 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr @@ -9,3 +9,4 @@ LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait< error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/borrowck/borrowck-reborrow-from-shorter-lived-andmut.stderr b/src/test/ui/borrowck/borrowck-reborrow-from-shorter-lived-andmut.stderr index 4142fc488c0dd..67b6f64eaa64f 100644 --- a/src/test/ui/borrowck/borrowck-reborrow-from-shorter-lived-andmut.stderr +++ b/src/test/ui/borrowck/borrowck-reborrow-from-shorter-lived-andmut.stderr @@ -10,3 +10,4 @@ LL | S { pointer: &mut *p.pointer } error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/continue-after-missing-main.stderr b/src/test/ui/continue-after-missing-main.stderr index 64d34cb6a1947..439f9e5221f66 100644 --- a/src/test/ui/continue-after-missing-main.stderr +++ b/src/test/ui/continue-after-missing-main.stderr @@ -21,4 +21,5 @@ LL | let _: AdaptedMatrixProvider<'original_data, MP> = tableau.provider().c error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0601`. +Some errors have detailed explanations: E0601, E0623. +For more information about an error, try `rustc --explain E0601`. diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 2ffb94348616b..a8341f62e1d14 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -77,4 +77,5 @@ LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0310`. +Some errors have detailed explanations: E0310, E0623. +For more information about an error, try `rustc --explain E0310`. diff --git a/src/test/ui/in-band-lifetimes/mismatched.stderr b/src/test/ui/in-band-lifetimes/mismatched.stderr index ec1045d5fae37..db72c20697108 100644 --- a/src/test/ui/in-band-lifetimes/mismatched.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched.stderr @@ -16,4 +16,5 @@ LL | fn foo2(x: &'a u32, y: &'b u32) -> &'a u32 { y } error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0621`. +Some errors have detailed explanations: E0621, E0623. +For more information about an error, try `rustc --explain E0621`. diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr index bc302e91c1c51..15891c9e7a62d 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr @@ -22,3 +22,4 @@ LL | x error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/issues/issue-17728.stderr b/src/test/ui/issues/issue-17728.stderr index 56dfb89456fe5..945dfc26b206d 100644 --- a/src/test/ui/issues/issue-17728.stderr +++ b/src/test/ui/issues/issue-17728.stderr @@ -29,4 +29,5 @@ LL | | } error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0308, E0623. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr index 56ca610019c4c..e9f5fc311dfc2 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr @@ -11,3 +11,4 @@ LL | if x > y { x } else { y } error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr index df34d18ee83a4..0d506f2b9fcb4 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr @@ -11,3 +11,4 @@ LL | x error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr index 22e14df9edc03..98a23613c3635 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr @@ -11,3 +11,4 @@ LL | if true { x } else { self } error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.stderr b/src/test/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.stderr index c0c75c7453d24..e505c9c0dc262 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.stderr @@ -8,3 +8,4 @@ LL | x.push(y); error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.stderr b/src/test/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.stderr index 57101cffe9b92..63b1c6db28f14 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.stderr @@ -9,3 +9,4 @@ LL | x.push(z); error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.stderr b/src/test/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.stderr index cab30636280a9..2f669efcf1eb4 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.stderr @@ -8,3 +8,4 @@ LL | let a: &mut Vec> = x; error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.stderr b/src/test/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.stderr index 384caca824892..258b6805acd5c 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.stderr @@ -8,3 +8,4 @@ LL | let a: &mut Vec> = x; error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr index 9251c5e2446f3..0aff80c6fbdd3 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr @@ -8,3 +8,4 @@ LL | *v = x; error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.stderr index adda66899cbf0..2e5ff6782d3b6 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.stderr @@ -16,3 +16,4 @@ LL | z.push((x,y)); error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr index 4341e8e663e19..8e41d7c54e68d 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr @@ -8,3 +8,4 @@ LL | x.b = y.b; error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr index b49ee0cfc7033..d659c88f69ef7 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr @@ -8,3 +8,4 @@ LL | x.a = x.b; error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr index a13c7e63cd6d9..374bbd93d0874 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr @@ -9,3 +9,4 @@ LL | x.push(y); error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr index 14faf6f460f52..94798d1ce2ab6 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr @@ -8,3 +8,4 @@ LL | x.push(y); error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr index e5696b74da9ec..9f5a79ed333dc 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr @@ -8,3 +8,4 @@ LL | x.push(y); error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr index bbf5d2452bfb9..2c87f8dbd2c2b 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr @@ -8,3 +8,4 @@ LL | x.push(y); error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr index f1bc1ca3aab01..60b92ed2b3247 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr @@ -10,3 +10,4 @@ LL | y = x.b; error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr index d8f6b8c49d30d..a220c8ddb2be6 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr @@ -8,3 +8,4 @@ LL | y.b = x; error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr index 08ae2c9db52e7..73472a8d02252 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr @@ -8,3 +8,4 @@ LL | y.b = x; error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr index ff286d722aacd..eb6e6f2e95e78 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr @@ -8,3 +8,4 @@ LL | x.b = y; error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr index 3d16c26568353..199f880b3c487 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr @@ -10,3 +10,4 @@ LL | x error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr index 10872d31ef206..838f43b37747f 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr @@ -10,3 +10,4 @@ LL | if true { x } else { self } error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr index 99e6e8bc5aa9b..d2cc3dba6a433 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr @@ -8,3 +8,4 @@ LL | y.push(z); error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr index 8ac221e333ad7..e8b0208f092f7 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr @@ -8,3 +8,4 @@ LL | x.push(y); error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr index bfecb4d33931b..2acc4eaf60f55 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr @@ -8,3 +8,4 @@ LL | y.push(z); error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.stderr index 053d577fa01ed..b2784827672b8 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.stderr @@ -8,3 +8,4 @@ LL | x.push(y); error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/object-lifetime/object-lifetime-default-mybox.stderr b/src/test/ui/object-lifetime/object-lifetime-default-mybox.stderr index f825475b96b03..89579fb1df3df 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-mybox.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-mybox.stderr @@ -27,4 +27,5 @@ LL | fn load2<'a>(ss: &MyBox) -> MyBox { error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0308, E0623. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr index fd78f82d0f321..36c66451cfaf6 100644 --- a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr +++ b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr @@ -27,4 +27,5 @@ LL | let _: fn(&mut &isize, &mut &isize) = a; error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0308, E0623. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr index 220c5493d19b1..a366bd2e5c2d7 100644 --- a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr +++ b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr @@ -38,4 +38,5 @@ LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0308, E0623. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.stderr b/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.stderr index 4e88be1c1e8a8..eb205a303dbdf 100644 --- a/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.stderr +++ b/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.stderr @@ -9,3 +9,4 @@ LL | a.bigger_region(b) error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.stderr b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.stderr index 6b1302b539402..de1073cd1d9da 100644 --- a/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.stderr +++ b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.stderr @@ -9,3 +9,4 @@ LL | f.method(b); error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/regions/regions-creating-enums3.stderr b/src/test/ui/regions/regions-creating-enums3.stderr index 763b62d945df8..2fc1fc3f68128 100644 --- a/src/test/ui/regions/regions-creating-enums3.stderr +++ b/src/test/ui/regions/regions-creating-enums3.stderr @@ -10,3 +10,4 @@ LL | Ast::Add(x, y) error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/regions/regions-free-region-ordering-callee.stderr b/src/test/ui/regions/regions-free-region-ordering-callee.stderr index 49cf1dfc642da..4648bf046bc77 100644 --- a/src/test/ui/regions/regions-free-region-ordering-callee.stderr +++ b/src/test/ui/regions/regions-free-region-ordering-callee.stderr @@ -22,3 +22,4 @@ LL | let z: &'b usize = &*x; error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/regions/regions-free-region-ordering-caller.migrate.stderr b/src/test/ui/regions/regions-free-region-ordering-caller.migrate.stderr index 9d6bae79ce5d8..a33d3583552dc 100644 --- a/src/test/ui/regions/regions-free-region-ordering-caller.migrate.stderr +++ b/src/test/ui/regions/regions-free-region-ordering-caller.migrate.stderr @@ -29,3 +29,4 @@ LL | let z: Option<&'a &'b usize> = None; error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/regions/regions-infer-contravariance-due-to-decl.stderr b/src/test/ui/regions/regions-infer-contravariance-due-to-decl.stderr index 9374818960d36..f3a0358b90fb0 100644 --- a/src/test/ui/regions/regions-infer-contravariance-due-to-decl.stderr +++ b/src/test/ui/regions/regions-infer-contravariance-due-to-decl.stderr @@ -12,3 +12,4 @@ LL | let _: Contravariant<'long> = c; error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/regions/regions-infer-covariance-due-to-decl.stderr b/src/test/ui/regions/regions-infer-covariance-due-to-decl.stderr index cd0a18a892f20..c3e2075fbc37e 100644 --- a/src/test/ui/regions/regions-infer-covariance-due-to-decl.stderr +++ b/src/test/ui/regions/regions-infer-covariance-due-to-decl.stderr @@ -11,3 +11,4 @@ LL | let _: Covariant<'short> = c; error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr b/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr index 0c3c342728c01..e260fccf8488c 100644 --- a/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr +++ b/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr @@ -27,4 +27,5 @@ LL | let _: fn(&mut &isize, &mut &isize) = a; error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0308, E0623. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.stderr b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.stderr index ead448df930fe..aca3a1ed05728 100644 --- a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.stderr +++ b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.stderr @@ -10,3 +10,4 @@ LL | &mut ***p error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.stderr b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.stderr index 064e89ee001c1..a9916dbe4f5ef 100644 --- a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.stderr +++ b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.stderr @@ -10,3 +10,4 @@ LL | &mut **p error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.stderr b/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.stderr index 6b3a488805f97..98f7a8136da91 100644 --- a/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.stderr +++ b/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.stderr @@ -9,3 +9,4 @@ LL | let _: S<'long, 'long> = c; error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/regions/regions-variance-contravariant-use-covariant.stderr b/src/test/ui/regions/regions-variance-contravariant-use-covariant.stderr index 44199881444ad..e7c106cbbe3d1 100644 --- a/src/test/ui/regions/regions-variance-contravariant-use-covariant.stderr +++ b/src/test/ui/regions/regions-variance-contravariant-use-covariant.stderr @@ -12,3 +12,4 @@ LL | let _: Contravariant<'long> = c; error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/regions/regions-variance-covariant-use-contravariant.stderr b/src/test/ui/regions/regions-variance-covariant-use-contravariant.stderr index 22ba8838893d6..e5e5261ba993f 100644 --- a/src/test/ui/regions/regions-variance-covariant-use-contravariant.stderr +++ b/src/test/ui/regions/regions-variance-covariant-use-contravariant.stderr @@ -11,3 +11,4 @@ LL | let _: Covariant<'short> = c; error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/regions/regions-variance-invariant-use-contravariant.stderr b/src/test/ui/regions/regions-variance-invariant-use-contravariant.stderr index a779b485ea701..2a2d5d019a129 100644 --- a/src/test/ui/regions/regions-variance-invariant-use-contravariant.stderr +++ b/src/test/ui/regions/regions-variance-invariant-use-contravariant.stderr @@ -11,3 +11,4 @@ LL | let _: Invariant<'short> = c; error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr index e3c261576e61e..37297032632e1 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr @@ -24,3 +24,4 @@ LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr index 3296e14f806e1..f3a7d14720171 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr @@ -24,3 +24,4 @@ LL | fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/self/elision/lt-ref-self-async.stderr b/src/test/ui/self/elision/lt-ref-self-async.stderr index 6b668d9f1f655..235b71ccab3a8 100644 --- a/src/test/ui/self/elision/lt-ref-self-async.stderr +++ b/src/test/ui/self/elision/lt-ref-self-async.stderr @@ -60,3 +60,4 @@ LL | f error: aborting due to 6 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/self/elision/lt-ref-self.stderr b/src/test/ui/self/elision/lt-ref-self.stderr index f73b3eddd3821..afd07d38f2fe4 100644 --- a/src/test/ui/self/elision/lt-ref-self.stderr +++ b/src/test/ui/self/elision/lt-ref-self.stderr @@ -60,3 +60,4 @@ LL | f error: aborting due to 6 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/self/elision/ref-mut-self-async.stderr b/src/test/ui/self/elision/ref-mut-self-async.stderr index 29fbec9fa7ae0..a656808d46bc2 100644 --- a/src/test/ui/self/elision/ref-mut-self-async.stderr +++ b/src/test/ui/self/elision/ref-mut-self-async.stderr @@ -60,3 +60,4 @@ LL | f error: aborting due to 6 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/self/elision/ref-mut-self.stderr b/src/test/ui/self/elision/ref-mut-self.stderr index 37984cd72fbac..3d6ae4b3dd388 100644 --- a/src/test/ui/self/elision/ref-mut-self.stderr +++ b/src/test/ui/self/elision/ref-mut-self.stderr @@ -60,3 +60,4 @@ LL | f error: aborting due to 6 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/self/elision/ref-mut-struct-async.stderr b/src/test/ui/self/elision/ref-mut-struct-async.stderr index 46591bfc9580f..2dc8cdb7d28ec 100644 --- a/src/test/ui/self/elision/ref-mut-struct-async.stderr +++ b/src/test/ui/self/elision/ref-mut-struct-async.stderr @@ -50,3 +50,4 @@ LL | f error: aborting due to 5 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/self/elision/ref-mut-struct.stderr b/src/test/ui/self/elision/ref-mut-struct.stderr index 2a4826905b94a..3fec398bb9879 100644 --- a/src/test/ui/self/elision/ref-mut-struct.stderr +++ b/src/test/ui/self/elision/ref-mut-struct.stderr @@ -50,3 +50,4 @@ LL | f error: aborting due to 5 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/self/elision/ref-self-async.stderr b/src/test/ui/self/elision/ref-self-async.stderr index c255d18936376..bda958241b67b 100644 --- a/src/test/ui/self/elision/ref-self-async.stderr +++ b/src/test/ui/self/elision/ref-self-async.stderr @@ -70,3 +70,4 @@ LL | f error: aborting due to 7 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/self/elision/ref-self.stderr b/src/test/ui/self/elision/ref-self.stderr index 611498f18da42..8343c8d349e16 100644 --- a/src/test/ui/self/elision/ref-self.stderr +++ b/src/test/ui/self/elision/ref-self.stderr @@ -70,3 +70,4 @@ LL | f error: aborting due to 7 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/self/elision/ref-struct-async.stderr b/src/test/ui/self/elision/ref-struct-async.stderr index c70facc931ec1..49a2a00953d87 100644 --- a/src/test/ui/self/elision/ref-struct-async.stderr +++ b/src/test/ui/self/elision/ref-struct-async.stderr @@ -50,3 +50,4 @@ LL | f error: aborting due to 5 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/self/elision/ref-struct.stderr b/src/test/ui/self/elision/ref-struct.stderr index 186e651c143bf..5116488dd22bb 100644 --- a/src/test/ui/self/elision/ref-struct.stderr +++ b/src/test/ui/self/elision/ref-struct.stderr @@ -50,3 +50,4 @@ LL | f error: aborting due to 5 previous errors +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.stderr index 21fdfcaef862e..76c14ccc14b45 100644 --- a/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.stderr +++ b/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.stderr @@ -8,3 +8,4 @@ LL | fn foo(x: &mut Vec<&'_ u8>, y: &'_ u8) { x.push(y); } error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/variance/variance-cell-is-invariant.stderr b/src/test/ui/variance/variance-cell-is-invariant.stderr index 91f6d7659ed4e..6fcd6460fe30a 100644 --- a/src/test/ui/variance/variance-cell-is-invariant.stderr +++ b/src/test/ui/variance/variance-cell-is-invariant.stderr @@ -12,3 +12,4 @@ LL | let _: Foo<'long> = c; error: aborting due to previous error +For more information about this error, try `rustc --explain E0623`. From 413ab57c0210ecbe92298c53ec4e1e39f97e4e4c Mon Sep 17 00:00:00 2001 From: Bryan Burgers Date: Fri, 8 Nov 2019 10:14:02 -0600 Subject: [PATCH 08/35] docs: Fix link to BufWriter::flush One of the links in the docs was being rendered as a literal open-bracket followed by a single quote, instead of being transformed into a link. Fix it to match the link earlier in the same paragraph. --- src/libstd/io/buffered.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index ad567c97c2c40..557da174d8941 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -369,7 +369,7 @@ impl Seek for BufReader { /// /// It is critical to call [`flush`] before `BufWriter` is dropped. Though /// dropping will attempt to flush the the contents of the buffer, any errors -/// that happen in the process of dropping will be ignored. Calling ['flush'] +/// that happen in the process of dropping will be ignored. Calling [`flush`] /// ensures that the buffer is empty and thus dropping will not even attempt /// file operations. /// From 1b8b2ee6f9e9e1fe109f40be4c756619d5c9aa3f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 9 Nov 2019 12:34:29 +0100 Subject: [PATCH 09/35] add raw ptr variant of UnsafeCell::get --- src/libcore/cell.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 87d8e7aff058d..0860d9c0cfa8b 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1548,6 +1548,36 @@ impl UnsafeCell { // #[repr(transparent)] self as *const UnsafeCell as *const T as *mut T } + + /// Gets a mutable pointer to the wrapped value. + /// + /// This can be cast to a pointer of any kind. + /// Ensure that the access is unique (no active references, mutable or not) + /// when casting to `&mut T`, and ensure that there are no mutations + /// or mutable aliases going on when casting to `&T` + /// + /// # Examples + /// + /// Gradual initialization of an `UnsafeCell`: + /// + /// ``` + /// #![feature(unsafe_cell_raw_get)] + /// use std::cell::UnsafeCell; + /// use std::mem::MaybeUninit; + /// + /// let m = MaybeUninit::>::uninit(); + /// unsafe { m.as_ptr().raw_get().write(5); } + /// let uc = unsafe { m.assume_init() }; + /// + /// assert_eq!(uc.into_inner(), 5); + /// ``` + #[inline] + #[unstable(feature = "unsafe_cell_raw_get", issue = "0")] + pub const fn raw_get(self: *const Self) -> *mut T { + // We can just cast the pointer from `UnsafeCell` to `T` because of + // #[repr(transparent)] + self as *const T as *mut T + } } #[stable(feature = "unsafe_cell_default", since = "1.10.0")] From 8d56bcc59c92c5770f585cd433230e7771da2dad Mon Sep 17 00:00:00 2001 From: Guanqun Lu Date: Tue, 29 Oct 2019 16:48:05 +0800 Subject: [PATCH 10/35] download .tar.xz if python3 is used --- src/bootstrap/bootstrap.py | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 4caf36a6f2a51..9cc58e03d5649 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -102,10 +102,10 @@ def verify(path, sha_path, verbose): return verified -def unpack(tarball, dst, verbose=False, match=None): +def unpack(tarball, tarball_suffix, dst, verbose=False, match=None): """Unpack the given tarball file""" print("extracting", tarball) - fname = os.path.basename(tarball).replace(".tar.gz", "") + fname = os.path.basename(tarball).replace(tarball_suffix, "") with contextlib.closing(tarfile.open(tarball)) as tar: for member in tar.getnames(): if "/" not in member: @@ -331,6 +331,18 @@ def __init__(self): self.use_vendored_sources = '' self.verbose = False + def support_xz(): + try: + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + temp_path = temp_file.name + with tarfile.open(temp_path, "w:xz") as tar: + pass + return True + except tarfile.CompressionError: + return False + + self.tarball_suffix = '.tar.xz' if support_xz() else '.tar.gz' + def download_stage0(self): """Fetch the build system for Rust, written in Rust @@ -349,12 +361,13 @@ def download_stage0(self): self.program_out_of_date(self.rustc_stamp())): if os.path.exists(self.bin_root()): shutil.rmtree(self.bin_root()) - filename = "rust-std-{}-{}.tar.gz".format( - rustc_channel, self.build) + filename = "rust-std-{}-{}{}".format( + rustc_channel, self.build, self.tarball_suffix) pattern = "rust-std-{}".format(self.build) self._download_stage0_helper(filename, pattern) - filename = "rustc-{}-{}.tar.gz".format(rustc_channel, self.build) + filename = "rustc-{}-{}{}".format(rustc_channel, self.build, + self.tarball_suffix) self._download_stage0_helper(filename, "rustc") self.fix_executable("{}/bin/rustc".format(self.bin_root())) self.fix_executable("{}/bin/rustdoc".format(self.bin_root())) @@ -365,14 +378,15 @@ def download_stage0(self): # libraries/binaries that are included in rust-std with # the system MinGW ones. if "pc-windows-gnu" in self.build: - filename = "rust-mingw-{}-{}.tar.gz".format( - rustc_channel, self.build) + filename = "rust-mingw-{}-{}{}".format( + rustc_channel, self.build, self.tarball_suffix) self._download_stage0_helper(filename, "rust-mingw") if self.cargo().startswith(self.bin_root()) and \ (not os.path.exists(self.cargo()) or self.program_out_of_date(self.cargo_stamp())): - filename = "cargo-{}-{}.tar.gz".format(cargo_channel, self.build) + filename = "cargo-{}-{}{}".format(cargo_channel, self.build, + self.tarball_suffix) self._download_stage0_helper(filename, "cargo") self.fix_executable("{}/bin/cargo".format(self.bin_root())) with output(self.cargo_stamp()) as cargo_stamp: @@ -388,7 +402,7 @@ def _download_stage0_helper(self, filename, pattern): tarball = os.path.join(rustc_cache, filename) if not os.path.exists(tarball): get("{}/{}".format(url, filename), tarball, verbose=self.verbose) - unpack(tarball, self.bin_root(), match=pattern, verbose=self.verbose) + unpack(tarball, self.tarball_suffix, self.bin_root(), match=pattern, verbose=self.verbose) @staticmethod def fix_executable(fname): From 0019371e3d878c1031bd7395b52ab40f2441049c Mon Sep 17 00:00:00 2001 From: Guanqun Lu Date: Tue, 12 Nov 2019 00:16:05 +0800 Subject: [PATCH 11/35] bootstrap: don't call support_xz in hot-path --- src/bootstrap/bootstrap.py | 43 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 9cc58e03d5649..730e8cf05d41d 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -331,17 +331,6 @@ def __init__(self): self.use_vendored_sources = '' self.verbose = False - def support_xz(): - try: - with tempfile.NamedTemporaryFile(delete=False) as temp_file: - temp_path = temp_file.name - with tarfile.open(temp_path, "w:xz") as tar: - pass - return True - except tarfile.CompressionError: - return False - - self.tarball_suffix = '.tar.xz' if support_xz() else '.tar.gz' def download_stage0(self): """Fetch the build system for Rust, written in Rust @@ -356,19 +345,30 @@ def download_stage0(self): rustc_channel = self.rustc_channel cargo_channel = self.cargo_channel + def support_xz(): + try: + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + temp_path = temp_file.name + with tarfile.open(temp_path, "w:xz") as tar: + pass + return True + except tarfile.CompressionError: + return False + if self.rustc().startswith(self.bin_root()) and \ (not os.path.exists(self.rustc()) or self.program_out_of_date(self.rustc_stamp())): if os.path.exists(self.bin_root()): shutil.rmtree(self.bin_root()) + tarball_suffix = '.tar.xz' if support_xz() else '.tar.gz' filename = "rust-std-{}-{}{}".format( - rustc_channel, self.build, self.tarball_suffix) + rustc_channel, self.build, tarball_suffix) pattern = "rust-std-{}".format(self.build) - self._download_stage0_helper(filename, pattern) + self._download_stage0_helper(filename, pattern, tarball_suffix) filename = "rustc-{}-{}{}".format(rustc_channel, self.build, - self.tarball_suffix) - self._download_stage0_helper(filename, "rustc") + tarball_suffix) + self._download_stage0_helper(filename, "rustc", tarball_suffix) self.fix_executable("{}/bin/rustc".format(self.bin_root())) self.fix_executable("{}/bin/rustdoc".format(self.bin_root())) with output(self.rustc_stamp()) as rust_stamp: @@ -379,20 +379,21 @@ def download_stage0(self): # the system MinGW ones. if "pc-windows-gnu" in self.build: filename = "rust-mingw-{}-{}{}".format( - rustc_channel, self.build, self.tarball_suffix) - self._download_stage0_helper(filename, "rust-mingw") + rustc_channel, self.build, tarball_suffix) + self._download_stage0_helper(filename, "rust-mingw", tarball_suffix) if self.cargo().startswith(self.bin_root()) and \ (not os.path.exists(self.cargo()) or self.program_out_of_date(self.cargo_stamp())): + tarball_suffix = '.tar.xz' if support_xz() else '.tar.gz' filename = "cargo-{}-{}{}".format(cargo_channel, self.build, - self.tarball_suffix) - self._download_stage0_helper(filename, "cargo") + tarball_suffix) + self._download_stage0_helper(filename, "cargo", tarball_suffix) self.fix_executable("{}/bin/cargo".format(self.bin_root())) with output(self.cargo_stamp()) as cargo_stamp: cargo_stamp.write(self.date) - def _download_stage0_helper(self, filename, pattern): + def _download_stage0_helper(self, filename, pattern, tarball_suffix): cache_dst = os.path.join(self.build_dir, "cache") rustc_cache = os.path.join(cache_dst, self.date) if not os.path.exists(rustc_cache): @@ -402,7 +403,7 @@ def _download_stage0_helper(self, filename, pattern): tarball = os.path.join(rustc_cache, filename) if not os.path.exists(tarball): get("{}/{}".format(url, filename), tarball, verbose=self.verbose) - unpack(tarball, self.tarball_suffix, self.bin_root(), match=pattern, verbose=self.verbose) + unpack(tarball, tarball_suffix, self.bin_root(), match=pattern, verbose=self.verbose) @staticmethod def fix_executable(fname): From f9f5a88bc4d2e62ea325be8a37e5811a951f234c Mon Sep 17 00:00:00 2001 From: Vytautas Astrauskas Date: Mon, 11 Nov 2019 16:09:03 +0100 Subject: [PATCH 12/35] Add a callback that allows compiler consumers to override queries. --- src/librustc_driver/lib.rs | 2 ++ src/librustc_interface/interface.rs | 11 +++++++++++ src/librustc_interface/passes.rs | 5 +++++ src/librustdoc/core.rs | 1 + src/librustdoc/test.rs | 1 + src/test/run-make-fulldeps/issue-19371/foo.rs | 1 + 6 files changed, 21 insertions(+) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index f2da4ae71f56a..4bea605125c15 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -181,6 +181,7 @@ pub fn run_compiler( crate_name: None, lint_caps: Default::default(), register_lints: None, + override_queries: None, }; callbacks.config(&mut config); config @@ -259,6 +260,7 @@ pub fn run_compiler( crate_name: None, lint_caps: Default::default(), register_lints: None, + override_queries: None, }; callbacks.config(&mut config); diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index 02068b2ce388d..fae4eb48c4a1b 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -12,6 +12,7 @@ use rustc_data_structures::OnDrop; use rustc_data_structures::sync::Lrc; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use rustc_parse::new_parser_from_source_str; +use rustc::ty; use std::path::PathBuf; use std::result; use std::sync::{Arc, Mutex}; @@ -38,6 +39,8 @@ pub struct Compiler { pub(crate) queries: Queries, pub(crate) crate_name: Option, pub(crate) register_lints: Option>, + pub(crate) override_queries: + Option, &mut ty::query::Providers<'_>)>, } impl Compiler { @@ -131,6 +134,13 @@ pub struct Config { /// Note that if you find a Some here you probably want to call that function in the new /// function being registered. pub register_lints: Option>, + + /// This is a callback from the driver that is called just after we have populated + /// the list of queries. + /// + /// The second parameter is local providers and the third parameter is external providers. + pub override_queries: + Option, &mut ty::query::Providers<'_>)>, } pub fn run_compiler_in_existing_thread_pool(config: Config, f: F) -> R @@ -157,6 +167,7 @@ where queries: Default::default(), crate_name: config.crate_name, register_lints: config.register_lints, + override_queries: config.override_queries, }; let _sess_abort_error = OnDrop(|| { diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 453007c564246..c57622b8b8fe5 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -786,6 +786,7 @@ pub fn create_global_ctxt( let codegen_backend = compiler.codegen_backend().clone(); let crate_name = crate_name.to_string(); let defs = mem::take(&mut resolver_outputs.definitions); + let override_queries = compiler.override_queries; let ((), result) = BoxedGlobalCtxt::new(static move || { let sess = &*sess; @@ -810,6 +811,10 @@ pub fn create_global_ctxt( default_provide_extern(&mut extern_providers); codegen_backend.provide_extern(&mut extern_providers); + if let Some(callback) = override_queries { + callback(sess, &mut local_providers, &mut extern_providers); + } + let gcx = TyCtxt::create_global_ctxt( sess, lint_store, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index b227f432a4e98..3d8b7ece04b41 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -335,6 +335,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt crate_name, lint_caps, register_lints: None, + override_queries: None, }; interface::run_compiler_in_existing_thread_pool(config, |compiler| { diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 553ef6a9c4788..04ee11dcf0771 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -79,6 +79,7 @@ pub fn run(options: Options) -> i32 { crate_name: options.crate_name.clone(), lint_caps: Default::default(), register_lints: None, + override_queries: None, }; let mut test_args = options.test_args.clone(); diff --git a/src/test/run-make-fulldeps/issue-19371/foo.rs b/src/test/run-make-fulldeps/issue-19371/foo.rs index 9582137eae91c..9f1850dfb4c90 100644 --- a/src/test/run-make-fulldeps/issue-19371/foo.rs +++ b/src/test/run-make-fulldeps/issue-19371/foo.rs @@ -60,6 +60,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) { crate_name: None, lint_caps: Default::default(), register_lints: None, + override_queries: None, }; interface::run_compiler(config, |compiler| { From e1cf38ac18163867078913861c509bd8dfc7e294 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 11 Nov 2019 14:50:26 -0500 Subject: [PATCH 13/35] Move injected_panic_runtime to CrateStore This was essentially a "query" previously (with no key, just always run once when resolving the crate dependencies), and remains so, just now in a way that isn't on Session. This removes the need for the `Once` as well. --- src/librustc/middle/cstore.rs | 1 + src/librustc/session/mod.rs | 3 --- src/librustc/ty/context.rs | 4 ++++ src/librustc_metadata/creader.rs | 6 +++--- src/librustc_metadata/cstore.rs | 2 ++ src/librustc_metadata/dependency_format.rs | 5 ++--- src/librustc_metadata/rmeta/decoder/cstore_impl.rs | 4 ++++ 7 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 1f4086227327e..f644853ebce8a 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -227,6 +227,7 @@ pub trait CrateStore { // utility functions fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata; fn metadata_encoding_version(&self) -> &[u8]; + fn injected_panic_runtime(&self) -> Option; } pub type CrateStoreDyn = dyn CrateStore + sync::Sync; diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 92e8e92d02a74..752a82f3115f0 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -2,7 +2,6 @@ pub use self::code_stats::{DataTypeKind, SizeKind, FieldInfo, VariantInfo}; use self::code_stats::CodeStats; use crate::dep_graph::cgu_reuse_tracker::CguReuseTracker; -use crate::hir::def_id::CrateNum; use rustc_data_structures::fingerprint::Fingerprint; use crate::lint; @@ -105,7 +104,6 @@ pub struct Session { /// dependency if it didn't already find one, and this tracks what was /// injected. pub allocator_kind: Once>, - pub injected_panic_runtime: Once>, /// Map from imported macro spans (which consist of /// the localized span for the macro body) to the @@ -1182,7 +1180,6 @@ fn build_session_( type_length_limit: Once::new(), const_eval_stack_frame_limit: 100, allocator_kind: Once::new(), - injected_panic_runtime: Once::new(), imported_macro_spans: OneThread::new(RefCell::new(FxHashMap::default())), incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)), cgu_reuse_tracker, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 04e0f6f4b56d7..d26b401201552 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1338,6 +1338,10 @@ impl<'tcx> TyCtxt<'tcx> { self.all_crate_nums(LOCAL_CRATE) } + pub fn injected_panic_runtime(self) -> Option { + self.cstore.injected_panic_runtime() + } + pub fn features(self) -> &'tcx feature_gate::Features { self.features_query(LOCAL_CRATE) } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 05e3ee3322e59..9c17b5b36e3be 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -531,7 +531,7 @@ impl<'a> CrateLoader<'a> { }); if !any_non_rlib { info!("panic runtime injection skipped, only generating rlib"); - self.sess.injected_panic_runtime.set(None); + self.cstore.injected_panic_runtime = None; return } @@ -563,7 +563,7 @@ impl<'a> CrateLoader<'a> { // we just don't need one at all, then we're done here and there's // nothing else to do. if !needs_panic_runtime || runtime_found { - self.sess.injected_panic_runtime.set(None); + self.cstore.injected_panic_runtime = None; return } @@ -600,7 +600,7 @@ impl<'a> CrateLoader<'a> { name, desired_strategy.desc())); } - self.sess.injected_panic_runtime.set(Some(cnum)); + self.cstore.injected_panic_runtime = Some(cnum); self.inject_dependency_if(cnum, "a panic runtime", &|data| data.root.needs_panic_runtime); } diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index c6c8ee575a98a..456596be83ff5 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -101,6 +101,7 @@ crate struct CrateMetadata { #[derive(Clone)] pub struct CStore { metas: IndexVec>>, + pub(crate) injected_panic_runtime: Option, } pub enum LoadedMacro { @@ -116,6 +117,7 @@ impl Default for CStore { // corresponding `CrateNum`. This first entry will always remain // `None`. metas: IndexVec::from_elem_n(None, 1), + injected_panic_runtime: None, } } } diff --git a/src/librustc_metadata/dependency_format.rs b/src/librustc_metadata/dependency_format.rs index 7f76a9730e198..dbf7fede1469f 100644 --- a/src/librustc_metadata/dependency_format.rs +++ b/src/librustc_metadata/dependency_format.rs @@ -184,7 +184,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList { // // Things like allocators and panic runtimes may not have been activated // quite yet, so do so here. - activate_injected_dep(*sess.injected_panic_runtime.get(), &mut ret, + activate_injected_dep(tcx.injected_panic_runtime(), &mut ret, &|cnum| tcx.is_panic_runtime(cnum)); // When dylib B links to dylib A, then when using B we must also link to A. @@ -244,7 +244,6 @@ fn add_library( } fn attempt_static(tcx: TyCtxt<'_>) -> Option { - let sess = &tcx.sess; let crates = cstore::used_crates(tcx, RequireStatic); if !crates.iter().by_ref().all(|&(_, ref p)| p.is_some()) { return None @@ -264,7 +263,7 @@ fn attempt_static(tcx: TyCtxt<'_>) -> Option { // Our allocator/panic runtime may not have been linked above if it wasn't // explicitly linked, which is the case for any injected dependency. Handle // that here and activate them. - activate_injected_dep(*sess.injected_panic_runtime.get(), &mut ret, + activate_injected_dep(tcx.injected_panic_runtime(), &mut ret, &|cnum| tcx.is_panic_runtime(cnum)); Some(ret) diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs index 015866548cd38..dc11a5aa196b7 100644 --- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs +++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs @@ -527,4 +527,8 @@ impl CrateStore for cstore::CStore { { rmeta::METADATA_HEADER } + + fn injected_panic_runtime(&self) -> Option { + self.injected_panic_runtime + } } From 2c6d6094840cd88422f50b2c7972199a00578319 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 11 Nov 2019 14:57:34 -0500 Subject: [PATCH 14/35] Move allocator_kind to CrateStore Similarly to the previous commit, there's no need for this to be in Session and have a Once around it. --- src/librustc/middle/cstore.rs | 2 ++ src/librustc/session/mod.rs | 7 ------- src/librustc/ty/context.rs | 5 +++++ src/librustc_codegen_ssa/back/symbol_export.rs | 2 +- src/librustc_codegen_ssa/base.rs | 2 +- src/librustc_metadata/creader.rs | 10 +++++----- src/librustc_metadata/cstore.rs | 3 +++ src/librustc_metadata/rmeta/decoder/cstore_impl.rs | 5 +++++ 8 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index f644853ebce8a..e5c80c3589494 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -15,6 +15,7 @@ use std::path::{Path, PathBuf}; use syntax::ast; use syntax::symbol::Symbol; use syntax_pos::Span; +use syntax::expand::allocator::AllocatorKind; use rustc_target::spec::Target; use rustc_data_structures::sync::{self, MetadataRef}; use rustc_macros::HashStable; @@ -228,6 +229,7 @@ pub trait CrateStore { fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata; fn metadata_encoding_version(&self) -> &[u8]; fn injected_panic_runtime(&self) -> Option; + fn allocator_kind(&self) -> Option; } pub type CrateStoreDyn = dyn CrateStore + sync::Sync; diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 752a82f3115f0..cae01d23db2c3 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -21,7 +21,6 @@ use errors::emitter::{Emitter, EmitterWriter}; use errors::emitter::HumanReadableErrorType; use errors::annotate_snippet_emitter_writer::{AnnotateSnippetEmitterWriter}; use syntax::edition::Edition; -use syntax::expand::allocator::AllocatorKind; use syntax::feature_gate::{self, AttributeType}; use syntax::json::JsonEmitter; use syntax::source_map; @@ -100,11 +99,6 @@ pub struct Session { /// The maximum number of stackframes allowed in const eval. pub const_eval_stack_frame_limit: usize, - /// The `metadata::creader` module may inject an allocator/`panic_runtime` - /// dependency if it didn't already find one, and this tracks what was - /// injected. - pub allocator_kind: Once>, - /// Map from imported macro spans (which consist of /// the localized span for the macro body) to the /// macro name and definition span in the source crate. @@ -1179,7 +1173,6 @@ fn build_session_( recursion_limit: Once::new(), type_length_limit: Once::new(), const_eval_stack_frame_limit: 100, - allocator_kind: Once::new(), imported_macro_spans: OneThread::new(RefCell::new(FxHashMap::default())), incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)), cgu_reuse_tracker, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index d26b401201552..7ed54ef9467c3 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -75,6 +75,7 @@ use syntax::source_map::MultiSpan; use syntax::feature_gate; use syntax::symbol::{Symbol, kw, sym}; use syntax_pos::Span; +use syntax::expand::allocator::AllocatorKind; pub struct AllArenas { pub interner: SyncDroplessArena, @@ -1342,6 +1343,10 @@ impl<'tcx> TyCtxt<'tcx> { self.cstore.injected_panic_runtime() } + pub fn allocator_kind(self) -> Option { + self.cstore.allocator_kind() + } + pub fn features(self) -> &'tcx feature_gate::Features { self.features_query(LOCAL_CRATE) } diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index 35b62603b076a..f8b3e0ffe5cd9 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -194,7 +194,7 @@ fn exported_symbols_provider_local( symbols.push((exported_symbol, SymbolExportLevel::C)); } - if tcx.sess.allocator_kind.get().is_some() { + if tcx.allocator_kind().is_some() { for method in ALLOCATOR_METHODS { let symbol_name = format!("__rust_{}", method.name); let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(&symbol_name)); diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index c3f2a5161ae1c..faa7b588e56e3 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -549,7 +549,7 @@ pub fn codegen_crate( }); let allocator_module = if any_dynamic_crate { None - } else if let Some(kind) = *tcx.sess.allocator_kind.get() { + } else if let Some(kind) = tcx.allocator_kind() { let llmod_id = cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string(); diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 9c17b5b36e3be..b4dea19d3dc3f 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -722,7 +722,7 @@ impl<'a> CrateLoader<'a> { } } - fn inject_allocator_crate(&self, krate: &ast::Crate) { + fn inject_allocator_crate(&mut self, krate: &ast::Crate) { let has_global_allocator = match &*global_allocator_spans(krate) { [span1, span2, ..] => { self.sess.struct_span_err(*span2, "cannot define multiple global allocators") @@ -742,7 +742,7 @@ impl<'a> CrateLoader<'a> { needs_allocator = needs_allocator || data.root.needs_allocator; }); if !needs_allocator { - self.sess.allocator_kind.set(None); + self.cstore.allocator_kind = None; return } @@ -758,7 +758,7 @@ impl<'a> CrateLoader<'a> { } }); if all_rlib { - self.sess.allocator_kind.set(None); + self.cstore.allocator_kind = None; return } @@ -795,7 +795,7 @@ impl<'a> CrateLoader<'a> { } }); if global_allocator.is_some() { - self.sess.allocator_kind.set(Some(AllocatorKind::Global)); + self.cstore.allocator_kind = Some(AllocatorKind::Global); return } @@ -816,7 +816,7 @@ impl<'a> CrateLoader<'a> { add `#[global_allocator]` to a static item \ that implements the GlobalAlloc trait."); } - self.sess.allocator_kind.set(Some(AllocatorKind::DefaultLib)); + self.cstore.allocator_kind = Some(AllocatorKind::DefaultLib); } fn inject_dependency_if(&self, diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 456596be83ff5..54857ce1b8281 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -14,6 +14,7 @@ use rustc_data_structures::svh::Svh; use syntax::ast; use syntax::edition::Edition; use syntax_expand::base::SyntaxExtension; +use syntax::expand::allocator::AllocatorKind; use syntax_pos; use proc_macro::bridge::client::ProcMacro; @@ -102,6 +103,7 @@ crate struct CrateMetadata { pub struct CStore { metas: IndexVec>>, pub(crate) injected_panic_runtime: Option, + pub(crate) allocator_kind: Option, } pub enum LoadedMacro { @@ -118,6 +120,7 @@ impl Default for CStore { // `None`. metas: IndexVec::from_elem_n(None, 1), injected_panic_runtime: None, + allocator_kind: None, } } } diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs index dc11a5aa196b7..a6cb3864ca7d4 100644 --- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs +++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs @@ -31,6 +31,7 @@ use syntax::attr; use syntax::source_map; use syntax::source_map::Spanned; use syntax::symbol::Symbol; +use syntax::expand::allocator::AllocatorKind; use syntax_pos::{Span, FileName}; macro_rules! provide { @@ -531,4 +532,8 @@ impl CrateStore for cstore::CStore { fn injected_panic_runtime(&self) -> Option { self.injected_panic_runtime } + + fn allocator_kind(&self) -> Option { + self.allocator_kind + } } From 1aee3e4d087755b40df50533dbfbc5fb80c90ff7 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 11 Nov 2019 14:22:23 -0800 Subject: [PATCH 15/35] Use a relative bindir for rustdoc to find rustc In bootstrap, we set `RUSTC_INSTALL_BINDIR` to `config.bindir`, so rustdoc can find rustc relative to the toolchain sysroot. However, if a distro script like Fedora's `%configure` sets an absolute path, then rustdoc's `sysroot.join(bin_path)` ignores that sysroot altogether. That would be OK once the toolchain is actually installed, but it breaks the in-tree doc tests during the build, since `/usr/bin/rustc` is still the old version. So now we try to make `RUSTC_INSTALL_BINDIR` relative to the sysroot prefix in the first place. --- src/bootstrap/builder.rs | 4 +++- src/bootstrap/config.rs | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 2748903f2d475..70b53cfc4e752 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1231,7 +1231,9 @@ impl<'a> Builder<'a> { cargo.arg("--frozen"); } - cargo.env("RUSTC_INSTALL_BINDIR", &self.config.bindir); + // Try to use a sysroot-relative bindir, in case it was configured absolutely. + let bindir = self.config.bindir_relative().unwrap_or(&self.config.bindir); + cargo.env("RUSTC_INSTALL_BINDIR", bindir); self.ci_env.force_coloring_in_ci(&mut cargo); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index d1bdfa0a76763..2493167f2f5e5 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -647,6 +647,17 @@ impl Config { config } + /// Try to find the relative path of `bindir`. + pub fn bindir_relative(&self) -> Option<&Path> { + let bindir = &self.bindir; + if bindir.is_relative() { + Some(bindir) + } else { + // Try to make it relative to the prefix. + bindir.strip_prefix(self.prefix.as_ref()?).ok() + } + } + /// Try to find the relative path of `libdir`. pub fn libdir_relative(&self) -> Option<&Path> { let libdir = self.libdir.as_ref()?; From db5fc10c21f7ee8ef7649628ae37e6481b8ca14c Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Mon, 28 Oct 2019 05:59:59 -0400 Subject: [PATCH 16/35] [mir-opt] Turn on the `ConstProp` pass by default perf.rlo shows that running the `ConstProp` pass results in across-the-board wins regardless of debug or opt complilation mode. As a result, we're turning it on to get the compile time benefits. `ConstProp` doesn't currently intern the memory used by its `Machine` so we can't yet propagate allocations which is why `ConstProp::should_const_prop()` checks if the value being propagated is a scalar or not. --- src/librustc_mir/transform/const_prop.rs | 41 ++++++++++++------- src/test/codegen/optimize-attr-1.rs | 6 +-- .../incremental/hashes/while_let_loops.rs | 10 ++--- src/test/incremental/hashes/while_loops.rs | 4 +- 4 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index a0d04bd593212..ecd45788d041c 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -641,8 +641,21 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } } - fn should_const_prop(&self) -> bool { - self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2 + fn should_const_prop(&mut self, op: OpTy<'tcx>) -> bool { + if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2 { + return true; + } else if self.tcx.sess.opts.debugging_opts.mir_opt_level == 0 { + return false; + } + + match *op { + interpret::Operand::Immediate(Immediate::Scalar(ScalarMaybeUndef::Scalar(s))) => + s.is_bits(), + interpret::Operand::Immediate(Immediate::ScalarPair(ScalarMaybeUndef::Scalar(l), + ScalarMaybeUndef::Scalar(r))) => + l.is_bits() && r.is_bits(), + _ => false + } } } @@ -742,15 +755,15 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { if self.can_const_prop[local] { trace!("propagated into {:?}", local); - if self.should_const_prop() { - let value = - self.get_const(local).expect("local was dead/uninitialized"); - trace!("replacing {:?} with {:?}", rval, value); - self.replace_with_const( - rval, - value, - statement.source_info, - ); + if let Some(value) = self.get_const(local) { + if self.should_const_prop(value) { + trace!("replacing {:?} with {:?}", rval, value); + self.replace_with_const( + rval, + value, + statement.source_info, + ); + } } } else { trace!("can't propagate into {:?}", local); @@ -852,7 +865,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { &msg, ); } else { - if self.should_const_prop() { + if self.should_const_prop(value) { if let ScalarMaybeUndef::Scalar(scalar) = value_const { *cond = self.operand_from_scalar( scalar, @@ -865,8 +878,8 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { } }, TerminatorKind::SwitchInt { ref mut discr, switch_ty, .. } => { - if self.should_const_prop() { - if let Some(value) = self.eval_operand(&discr, source_info) { + if let Some(value) = self.eval_operand(&discr, source_info) { + if self.should_const_prop(value) { if let ScalarMaybeUndef::Scalar(scalar) = self.ecx.read_scalar(value).unwrap() { *discr = self.operand_from_scalar(scalar, switch_ty, source_info.span); diff --git a/src/test/codegen/optimize-attr-1.rs b/src/test/codegen/optimize-attr-1.rs index 4a5b7c05231dc..a8be10ba3ce0a 100644 --- a/src/test/codegen/optimize-attr-1.rs +++ b/src/test/codegen/optimize-attr-1.rs @@ -8,7 +8,7 @@ // CHECK-LABEL: define i32 @nothing // CHECK-SAME: [[NOTHING_ATTRS:#[0-9]+]] -// NO-OPT: ret i32 %_1.0 +// NO-OPT: ret i32 4 // SIZE-OPT: ret i32 4 // SPEEC-OPT: ret i32 4 #[no_mangle] @@ -18,7 +18,7 @@ pub fn nothing() -> i32 { // CHECK-LABEL: define i32 @size // CHECK-SAME: [[SIZE_ATTRS:#[0-9]+]] -// NO-OPT: ret i32 %_1.0 +// NO-OPT: ret i32 6 // SIZE-OPT: ret i32 6 // SPEED-OPT: ret i32 6 #[optimize(size)] @@ -31,7 +31,7 @@ pub fn size() -> i32 { // NO-OPT-SAME: [[NOTHING_ATTRS]] // SPEED-OPT-SAME: [[NOTHING_ATTRS]] // SIZE-OPT-SAME: [[SPEED_ATTRS:#[0-9]+]] -// NO-OPT: ret i32 %_1.0 +// NO-OPT: ret i32 8 // SIZE-OPT: ret i32 8 // SPEED-OPT: ret i32 8 #[optimize(speed)] diff --git a/src/test/incremental/hashes/while_let_loops.rs b/src/test/incremental/hashes/while_let_loops.rs index 1e628d019196b..615f1fe1fd0b8 100644 --- a/src/test/incremental/hashes/while_let_loops.rs +++ b/src/test/incremental/hashes/while_let_loops.rs @@ -48,7 +48,7 @@ pub fn change_loop_condition() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")] #[rustc_clean(cfg="cfail3")] pub fn change_loop_condition() { let mut _x = 0; @@ -70,7 +70,7 @@ pub fn add_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, typeck_tables_of")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, typeck_tables_of")] #[rustc_clean(cfg="cfail3")] pub fn add_break() { let mut _x = 0; @@ -141,7 +141,7 @@ pub fn change_break_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")] #[rustc_clean(cfg="cfail3")] pub fn change_break_label() { let mut _x = 0; @@ -191,7 +191,7 @@ pub fn change_continue_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_label() { let mut _x = 0; @@ -216,7 +216,7 @@ pub fn change_continue_to_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_to_break() { let mut _x = 0; diff --git a/src/test/incremental/hashes/while_loops.rs b/src/test/incremental/hashes/while_loops.rs index 295c2244879f8..70d0f86c3d268 100644 --- a/src/test/incremental/hashes/while_loops.rs +++ b/src/test/incremental/hashes/while_loops.rs @@ -48,7 +48,7 @@ pub fn change_loop_condition() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")] #[rustc_clean(cfg="cfail3")] pub fn change_loop_condition() { let mut _x = 0; @@ -191,7 +191,7 @@ pub fn change_continue_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_label() { let mut _x = 0; From e8f3a9ffbe0dc435d43767b31cc122ccc325f4c1 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Mon, 11 Nov 2019 13:25:19 +0000 Subject: [PATCH 17/35] add Result::map_or --- src/libcore/result.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index ed40a5f31d9bd..06c7041703ae5 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -514,6 +514,28 @@ impl Result { } } + /// Applies a function to the contained value (if any), + /// or returns the provided default (if not). + /// + /// # Examples + /// + /// ``` + /// #![feature(result_map_or)] + /// let x: Result<_, &str> = Ok("foo"); + /// assert_eq!(x.map_or(42, |v| v.len()), 3); + /// + /// let x: Result<&str, _> = Err("bar"); + /// assert_eq!(x.map_or(42, |v| v.len()), 42); + /// ``` + #[inline] + #[unstable(feature = "result_map_or", issue = "66293")] + pub fn map_or U>(self, default: U, f: F) -> U { + match self { + Ok(t) => f(t), + Err(_) => default, + } + } + /// Maps a `Result` to `U` by applying a function to a /// contained [`Ok`] value, or a fallback function to a /// contained [`Err`] value. From eb99c73e04ae48a7847c703cb29f5b0bb8595f08 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 12 Nov 2019 10:36:56 +0000 Subject: [PATCH 18/35] Match constructor first in Constructor methods This makes it easier to add new non-standard constructors, and this also ensures that we don't forget cases when adding a new constructor. --- src/librustc_mir/hair/pattern/_match.rs | 211 ++++++++++++------------ 1 file changed, 105 insertions(+), 106 deletions(-) diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 982330baf9c95..b19ddf7a77db8 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -781,65 +781,68 @@ impl<'tcx> Constructor<'tcx> { ty: Ty<'tcx>, ) -> Vec> { debug!("wildcard_subpatterns({:#?}, {:?})", self, ty); - match ty.kind { - ty::Tuple(ref fs) => { - fs.into_iter().map(|t| t.expect_ty()).map(Pat::wildcard_from_ty).collect() - } - ty::Slice(ty) | ty::Array(ty, _) => match *self { - FixedLenSlice(length) => (0..length).map(|_| Pat::wildcard_from_ty(ty)).collect(), - VarLenSlice(prefix, suffix) => { - (0..prefix + suffix).map(|_| Pat::wildcard_from_ty(ty)).collect() + + match self { + Single | Variant(_) => match ty.kind { + ty::Tuple(ref fs) => { + fs.into_iter().map(|t| t.expect_ty()).map(Pat::wildcard_from_ty).collect() } - ConstantValue(..) => vec![], - _ => bug!("bad slice pattern {:?} {:?}", self, ty), - }, - ty::Ref(_, rty, _) => vec![Pat::wildcard_from_ty(rty)], - ty::Adt(adt, substs) => { - if adt.is_box() { - // Use T as the sub pattern type of Box. - vec![Pat::wildcard_from_ty(substs.type_at(0))] - } else { - let variant = &adt.variants[self.variant_index_for_adt(cx, adt)]; - let is_non_exhaustive = - variant.is_field_list_non_exhaustive() && !cx.is_local(ty); - variant - .fields - .iter() - .map(|field| { - let is_visible = - adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx); - let is_uninhabited = cx.is_uninhabited(field.ty(cx.tcx, substs)); - match (is_visible, is_non_exhaustive, is_uninhabited) { - // Treat all uninhabited types in non-exhaustive variants as - // `TyErr`. - (_, true, true) => cx.tcx.types.err, - // Treat all non-visible fields as `TyErr`. They can't appear in - // any other pattern from this match (because they are private), so - // their type does not matter - but we don't want to know they are - // uninhabited. - (false, ..) => cx.tcx.types.err, - (true, ..) => { - let ty = field.ty(cx.tcx, substs); - match ty.kind { - // If the field type returned is an array of an unknown - // size return an TyErr. - ty::Array(_, len) - if len - .try_eval_usize(cx.tcx, cx.param_env) - .is_none() => - { - cx.tcx.types.err + ty::Ref(_, rty, _) => vec![Pat::wildcard_from_ty(rty)], + ty::Adt(adt, substs) => { + if adt.is_box() { + // Use T as the sub pattern type of Box. + vec![Pat::wildcard_from_ty(substs.type_at(0))] + } else { + let variant = &adt.variants[self.variant_index_for_adt(cx, adt)]; + let is_non_exhaustive = + variant.is_field_list_non_exhaustive() && !cx.is_local(ty); + variant + .fields + .iter() + .map(|field| { + let is_visible = adt.is_enum() + || field.vis.is_accessible_from(cx.module, cx.tcx); + let is_uninhabited = cx.is_uninhabited(field.ty(cx.tcx, substs)); + match (is_visible, is_non_exhaustive, is_uninhabited) { + // Treat all uninhabited types in non-exhaustive variants as + // `TyErr`. + (_, true, true) => cx.tcx.types.err, + // Treat all non-visible fields as `TyErr`. They can't appear + // in any other pattern from this match (because they are + // private), so their type does not matter - but we don't want + // to know they are uninhabited. + (false, ..) => cx.tcx.types.err, + (true, ..) => { + let ty = field.ty(cx.tcx, substs); + match ty.kind { + // If the field type returned is an array of an unknown + // size return an TyErr. + ty::Array(_, len) + if len + .try_eval_usize(cx.tcx, cx.param_env) + .is_none() => + { + cx.tcx.types.err + } + _ => ty, } - _ => ty, } } - } - }) - .map(Pat::wildcard_from_ty) - .collect() + }) + .map(Pat::wildcard_from_ty) + .collect() + } } - } - _ => vec![], + _ => vec![], + }, + FixedLenSlice(_) | VarLenSlice(..) => match ty.kind { + ty::Slice(ty) | ty::Array(ty, _) => { + let arity = self.arity(cx, ty); + (0..arity).map(|_| Pat::wildcard_from_ty(ty)).collect() + } + _ => bug!("bad slice pattern {:?} {:?}", self, ty), + }, + ConstantValue(..) | ConstantRange(..) => vec![], } } @@ -850,19 +853,19 @@ impl<'tcx> Constructor<'tcx> { /// A struct pattern's arity is the number of fields it contains, etc. fn arity<'a>(&self, cx: &MatchCheckCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> u64 { debug!("Constructor::arity({:#?}, {:?})", self, ty); - match ty.kind { - ty::Tuple(ref fs) => fs.len() as u64, - ty::Slice(..) | ty::Array(..) => match *self { - FixedLenSlice(length) => length, - VarLenSlice(prefix, suffix) => prefix + suffix, - ConstantValue(..) => 0, - _ => bug!("bad slice pattern {:?} {:?}", self, ty), + match self { + Single | Variant(_) => match ty.kind { + ty::Tuple(ref fs) => fs.len() as u64, + ty::Slice(..) | ty::Array(..) => bug!("bad slice pattern {:?} {:?}", self, ty), + ty::Ref(..) => 1, + ty::Adt(adt, _) => { + adt.variants[self.variant_index_for_adt(cx, adt)].fields.len() as u64 + } + _ => 0, }, - ty::Ref(..) => 1, - ty::Adt(adt, _) => { - adt.variants[self.variant_index_for_adt(cx, adt)].fields.len() as u64 - } - _ => 0, + FixedLenSlice(length) => *length, + VarLenSlice(prefix, suffix) => prefix + suffix, + ConstantValue(..) | ConstantRange(..) => 0, } } @@ -886,53 +889,49 @@ impl<'tcx> Constructor<'tcx> { pats: impl IntoIterator>, ) -> Pat<'tcx> { let mut subpatterns = pats.into_iter(); - let pat = match ty.kind { - ty::Adt(..) | ty::Tuple(..) => { - let subpatterns = subpatterns - .enumerate() - .map(|(i, p)| FieldPat { field: Field::new(i), pattern: p }) - .collect(); - - if let ty::Adt(adt, substs) = ty.kind { - if adt.is_enum() { - PatKind::Variant { - adt_def: adt, - substs, - variant_index: self.variant_index_for_adt(cx, adt), - subpatterns, + + let pat = match self { + Single | Variant(_) => match ty.kind { + ty::Adt(..) | ty::Tuple(..) => { + let subpatterns = subpatterns + .enumerate() + .map(|(i, p)| FieldPat { field: Field::new(i), pattern: p }) + .collect(); + + if let ty::Adt(adt, substs) = ty.kind { + if adt.is_enum() { + PatKind::Variant { + adt_def: adt, + substs, + variant_index: self.variant_index_for_adt(cx, adt), + subpatterns, + } + } else { + PatKind::Leaf { subpatterns } } } else { PatKind::Leaf { subpatterns } } - } else { - PatKind::Leaf { subpatterns } } - } - - ty::Ref(..) => PatKind::Deref { subpattern: subpatterns.nth(0).unwrap() }, - - ty::Slice(_) | ty::Array(..) => match self { - FixedLenSlice(_) => { - PatKind::Slice { prefix: subpatterns.collect(), slice: None, suffix: vec![] } - } - VarLenSlice(prefix_len, _suffix_len) => { - let prefix = subpatterns.by_ref().take(*prefix_len as usize).collect(); - let suffix = subpatterns.collect(); - let wild = Pat::wildcard_from_ty(ty); - PatKind::Slice { prefix, slice: Some(wild), suffix } - } - _ => bug!("bad slice pattern {:?} {:?}", self, ty), - }, - - _ => match *self { - ConstantValue(value, _) => PatKind::Constant { value }, - ConstantRange(lo, hi, ty, end, _) => PatKind::Range(PatRange { - lo: ty::Const::from_bits(cx.tcx, lo, ty::ParamEnv::empty().and(ty)), - hi: ty::Const::from_bits(cx.tcx, hi, ty::ParamEnv::empty().and(ty)), - end, - }), + ty::Ref(..) => PatKind::Deref { subpattern: subpatterns.nth(0).unwrap() }, + ty::Slice(_) | ty::Array(..) => bug!("bad slice pattern {:?} {:?}", self, ty), _ => PatKind::Wild, }, + FixedLenSlice(_) => { + PatKind::Slice { prefix: subpatterns.collect(), slice: None, suffix: vec![] } + } + &VarLenSlice(prefix_len, _) => { + let prefix = subpatterns.by_ref().take(prefix_len as usize).collect(); + let suffix = subpatterns.collect(); + let wild = Pat::wildcard_from_ty(ty); + PatKind::Slice { prefix, slice: Some(wild), suffix } + } + &ConstantValue(value, _) => PatKind::Constant { value }, + &ConstantRange(lo, hi, ty, end, _) => PatKind::Range(PatRange { + lo: ty::Const::from_bits(cx.tcx, lo, ty::ParamEnv::empty().and(ty)), + hi: ty::Const::from_bits(cx.tcx, hi, ty::ParamEnv::empty().and(ty)), + end, + }), }; Pat { ty, span: DUMMY_SP, kind: Box::new(pat) } From 357d53c4ce6eed4d93fe1ed576613687d34d10b2 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 12 Nov 2019 12:44:00 +0000 Subject: [PATCH 19/35] Introduce Constructor::NonExhaustive It counts as an extra constructor for types that are not allowed to be matched exhaustively. --- src/librustc_mir/hair/pattern/_match.rs | 115 ++++++++++++------------ 1 file changed, 58 insertions(+), 57 deletions(-) diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index b19ddf7a77db8..fbf073d9423d9 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -590,6 +590,8 @@ enum Constructor<'tcx> { FixedLenSlice(u64), /// Slice patterns. Captures any array constructor of `length >= i + j`. VarLenSlice(u64, u64), + /// Fake extra constructor for enums that aren't allowed to be matched exhaustively. + NonExhaustive, } // Ignore spans when comparing, they don't carry semantic information as they are only for lints. @@ -597,6 +599,7 @@ impl<'tcx> std::cmp::PartialEq for Constructor<'tcx> { fn eq(&self, other: &Self) -> bool { match (self, other) { (Constructor::Single, Constructor::Single) => true, + (Constructor::NonExhaustive, Constructor::NonExhaustive) => true, (Constructor::Variant(a), Constructor::Variant(b)) => a == b, (Constructor::ConstantValue(a, _), Constructor::ConstantValue(b, _)) => a == b, ( @@ -771,6 +774,8 @@ impl<'tcx> Constructor<'tcx> { // ranges have been omitted. remaining_ctors } + // This constructor is never covered by anything else + NonExhaustive => vec![NonExhaustive], } } @@ -842,7 +847,7 @@ impl<'tcx> Constructor<'tcx> { } _ => bug!("bad slice pattern {:?} {:?}", self, ty), }, - ConstantValue(..) | ConstantRange(..) => vec![], + ConstantValue(..) | ConstantRange(..) | NonExhaustive => vec![], } } @@ -865,7 +870,7 @@ impl<'tcx> Constructor<'tcx> { }, FixedLenSlice(length) => *length, VarLenSlice(prefix, suffix) => prefix + suffix, - ConstantValue(..) | ConstantRange(..) => 0, + ConstantValue(..) | ConstantRange(..) | NonExhaustive => 0, } } @@ -932,6 +937,7 @@ impl<'tcx> Constructor<'tcx> { hi: ty::Const::from_bits(cx.tcx, hi, ty::ParamEnv::empty().and(ty)), end, }), + NonExhaustive => PatKind::Wild, }; Pat { ty, span: DUMMY_SP, kind: Box::new(pat) } @@ -1193,6 +1199,36 @@ fn all_constructors<'a, 'tcx>( } } }; + + // FIXME: currently the only way I know of something can + // be a privately-empty enum is when the exhaustive_patterns + // feature flag is not present, so this is only + // needed for that case. + let is_privately_empty = ctors.is_empty() && !cx.is_uninhabited(pcx.ty); + let is_declared_nonexhaustive = cx.is_non_exhaustive_enum(pcx.ty) && !cx.is_local(pcx.ty); + let is_non_exhaustive = is_privately_empty + || is_declared_nonexhaustive + || (pcx.ty.is_ptr_sized_integral() && !cx.tcx.features().precise_pointer_size_matching); + if is_non_exhaustive { + // If our scrutinee is *privately* an empty enum, we must treat it as though it had an + // "unknown" constructor (in that case, all other patterns obviously can't be variants) to + // avoid exposing its emptyness. See the `match_privately_empty` test for details. + // + // If the enum is declared as `#[non_exhaustive]`, we treat it as if it had an additionnal + // "unknown" constructor. However there is no point in enumerating all possible variants, + // because the user can't actually match against them themselves. So we return only the + // fictitious constructor. + // E.g., in an example like: + // ``` + // let err: io::ErrorKind = ...; + // match err { + // io::ErrorKind::NotFound => {}, + // } + // ``` + // we don't want to show every possible IO error, but instead have only `_` as the witness. + return vec![NonExhaustive]; + } + ctors } @@ -1591,9 +1627,6 @@ pub fn is_useful<'p, 'a, 'tcx>( let all_ctors = all_constructors(cx, pcx); debug!("all_ctors = {:#?}", all_ctors); - let is_privately_empty = all_ctors.is_empty() && !cx.is_uninhabited(pcx.ty); - let is_declared_nonexhaustive = cx.is_non_exhaustive_enum(pcx.ty) && !cx.is_local(pcx.ty); - // `missing_ctors` is the set of constructors from the same type as the // first column of `matrix` that are matched only by wildcard patterns // from the first column. @@ -1601,38 +1634,15 @@ pub fn is_useful<'p, 'a, 'tcx>( // Therefore, if there is some pattern that is unmatched by `matrix`, // it will still be unmatched if the first constructor is replaced by // any of the constructors in `missing_ctors` - // - // However, if our scrutinee is *privately* an empty enum, we - // must treat it as though it had an "unknown" constructor (in - // that case, all other patterns obviously can't be variants) - // to avoid exposing its emptyness. See the `match_privately_empty` - // test for details. - // - // FIXME: currently the only way I know of something can - // be a privately-empty enum is when the exhaustive_patterns - // feature flag is not present, so this is only - // needed for that case. - - // Missing constructors are those that are not matched by any - // non-wildcard patterns in the current column. To determine if - // the set is empty, we can check that `.peek().is_none()`, so - // we only fully construct them on-demand, because they're rarely used and can be big. - let missing_ctors = MissingConstructors::new(cx.tcx, cx.param_env, all_ctors, used_ctors); - debug!( - "missing_ctors.empty()={:#?} is_privately_empty={:#?} is_declared_nonexhaustive={:#?}", - missing_ctors.is_empty(), - is_privately_empty, - is_declared_nonexhaustive - ); + // Missing constructors are those that are not matched by any non-wildcard patterns in the + // current column. We only fully construct them on-demand, because they're rarely used and + // can be big. + let missing_ctors = MissingConstructors::new(cx.tcx, cx.param_env, all_ctors, used_ctors); - // For privately empty and non-exhaustive enums, we work as if there were an "extra" - // `_` constructor for the type, so we can never match over all constructors. - let is_non_exhaustive = is_privately_empty - || is_declared_nonexhaustive - || (pcx.ty.is_ptr_sized_integral() && !cx.tcx.features().precise_pointer_size_matching); + debug!("missing_ctors.empty()={:#?}", missing_ctors.is_empty(),); - if missing_ctors.is_empty() && !is_non_exhaustive { + if missing_ctors.is_empty() { let (all_ctors, _) = missing_ctors.into_inner(); split_grouped_constructors(cx.tcx, cx.param_env, pcx, all_ctors, matrix, DUMMY_SP, None) .into_iter() @@ -1661,26 +1671,9 @@ pub fn is_useful<'p, 'a, 'tcx>( // // we can report 3 witnesses: `S`, `E`, and `W`. // - // However, there are 2 cases where we don't want + // However, there is a case where we don't want // to do this and instead report a single `_` witness: - // - // 1) If the user is matching against a non-exhaustive - // enum, there is no point in enumerating all possible - // variants, because the user can't actually match - // against them themselves, e.g., in an example like: - // ``` - // let err: io::ErrorKind = ...; - // match err { - // io::ErrorKind::NotFound => {}, - // } - // ``` - // we don't want to show every possible IO error, - // but instead have `_` as the witness (this is - // actually *required* if the user specified *all* - // IO errors, but is probably what we want in every - // case). - // - // 2) If the user didn't actually specify a constructor + // if the user didn't actually specify a constructor // in this arm, e.g., in // ``` // let x: (Direction, Direction, bool) = ...; @@ -1690,7 +1683,7 @@ pub fn is_useful<'p, 'a, 'tcx>( // `(, , true)` - we are // satisfied with `(_, _, true)`. In this case, // `used_ctors` is empty. - if is_non_exhaustive || missing_ctors.all_ctors_are_missing() { + if missing_ctors.all_ctors_are_missing() { // All constructors are unused. Add a wild pattern // rather than each individual constructor. usefulness.apply_wildcard(pcx.ty) @@ -2217,13 +2210,21 @@ fn patterns_for_variant<'p, 'a: 'p, 'tcx>( /// fields filled with wild patterns. fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>( cx: &mut MatchCheckCtxt<'a, 'tcx>, - pat: &'q Pat<'tcx>, + mut pat: &'q Pat<'tcx>, constructor: &Constructor<'tcx>, ctor_wild_subpatterns: &[&'p Pat<'tcx>], ) -> Option> { + while let PatKind::AscribeUserType { ref subpattern, .. } = *pat.kind { + pat = subpattern; + } + + if let NonExhaustive = constructor { + // Only a wildcard pattern can match the special extra constructor + return if pat.is_wildcard() { Some(PatStack::default()) } else { None }; + } + let result = match *pat.kind { - PatKind::AscribeUserType { ref subpattern, .. } => PatStack::from_pattern(subpattern) - .specialize_constructor(cx, constructor, ctor_wild_subpatterns), + PatKind::AscribeUserType { .. } => bug!(), // Handled above PatKind::Binding { .. } | PatKind::Wild => { Some(PatStack::from_slice(ctor_wild_subpatterns)) From e398d897b09f69bc4b5a1ab531db1c8742001bff Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 12 Nov 2019 14:51:59 +0000 Subject: [PATCH 20/35] Move NonExhaustive checks to the relevant match branches --- src/librustc_mir/hair/pattern/_match.rs | 105 ++++++++++++------------ 1 file changed, 54 insertions(+), 51 deletions(-) diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index fbf073d9423d9..8e574cc961b2b 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -560,13 +560,6 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { } } - fn is_non_exhaustive_enum(&self, ty: Ty<'tcx>) -> bool { - match ty.kind { - ty::Adt(adt_def, ..) => adt_def.is_variant_list_non_exhaustive(), - _ => false, - } - } - fn is_local(&self, ty: Ty<'tcx>) -> bool { match ty.kind { ty::Adt(adt_def, ..) => adt_def.did.is_local(), @@ -1133,7 +1126,7 @@ fn all_constructors<'a, 'tcx>( pcx: PatCtxt<'tcx>, ) -> Vec> { debug!("all_constructors({:?})", pcx.ty); - let ctors = match pcx.ty.kind { + match pcx.ty.kind { ty::Bool => [true, false] .iter() .map(|&b| ConstantValue(ty::Const::from_bool(cx.tcx, b), pcx.span)) @@ -1150,17 +1143,49 @@ fn all_constructors<'a, 'tcx>( vec![VarLenSlice(0, 0)] } } - ty::Adt(def, substs) if def.is_enum() => def - .variants - .iter() - .filter(|v| { - !cx.tcx.features().exhaustive_patterns - || !v - .uninhabited_from(cx.tcx, substs, def.adt_kind()) - .contains(cx.tcx, cx.module) - }) - .map(|v| Variant(v.def_id)) - .collect(), + ty::Adt(def, substs) if def.is_enum() => { + let ctors: Vec<_> = def + .variants + .iter() + .filter(|v| { + !cx.tcx.features().exhaustive_patterns + || !v + .uninhabited_from(cx.tcx, substs, def.adt_kind()) + .contains(cx.tcx, cx.module) + }) + .map(|v| Variant(v.def_id)) + .collect(); + + // If our scrutinee is *privately* an empty enum, we must treat it as though it had an + // "unknown" constructor (in that case, all other patterns obviously can't be variants) + // to avoid exposing its emptyness. See the `match_privately_empty` test for details. + // FIXME: currently the only way I know of something can be a privately-empty enum is + // when the exhaustive_patterns feature flag is not present, so this is only needed for + // that case. + let is_privately_empty = ctors.is_empty() && !cx.is_uninhabited(pcx.ty); + // If the enum is declared as `#[non_exhaustive]`, we treat it as if it had an + // additionnal "unknown" constructor. + let is_declared_nonexhaustive = + def.is_variant_list_non_exhaustive() && !cx.is_local(pcx.ty); + + if is_privately_empty || is_declared_nonexhaustive { + // There is no point in enumerating all possible variants, because the user can't + // actually match against them themselves. So we return only the fictitious + // constructor. + // E.g., in an example like: + // ``` + // let err: io::ErrorKind = ...; + // match err { + // io::ErrorKind::NotFound => {}, + // } + // ``` + // we don't want to show every possible IO error, but instead have only `_` as the + // witness. + vec![NonExhaustive] + } else { + ctors + } + } ty::Char => { vec![ // The valid Unicode Scalar Value ranges. @@ -1180,6 +1205,15 @@ fn all_constructors<'a, 'tcx>( ), ] } + ty::Int(_) | ty::Uint(_) + if pcx.ty.is_ptr_sized_integral() + && !cx.tcx.features().precise_pointer_size_matching => + { + // `usize`/`isize` are not allowed to be matched exhaustively unless the + // `precise_pointer_size_matching` feature is enabled. So we treat those types like + // `#[non_exhaustive]` enums by returning a special unmatcheable constructor. + vec![NonExhaustive] + } ty::Int(ity) => { let bits = Integer::from_attr(&cx.tcx, SignedInt(ity)).size().bits() as u128; let min = 1u128 << (bits - 1); @@ -1198,38 +1232,7 @@ fn all_constructors<'a, 'tcx>( vec![Single] } } - }; - - // FIXME: currently the only way I know of something can - // be a privately-empty enum is when the exhaustive_patterns - // feature flag is not present, so this is only - // needed for that case. - let is_privately_empty = ctors.is_empty() && !cx.is_uninhabited(pcx.ty); - let is_declared_nonexhaustive = cx.is_non_exhaustive_enum(pcx.ty) && !cx.is_local(pcx.ty); - let is_non_exhaustive = is_privately_empty - || is_declared_nonexhaustive - || (pcx.ty.is_ptr_sized_integral() && !cx.tcx.features().precise_pointer_size_matching); - if is_non_exhaustive { - // If our scrutinee is *privately* an empty enum, we must treat it as though it had an - // "unknown" constructor (in that case, all other patterns obviously can't be variants) to - // avoid exposing its emptyness. See the `match_privately_empty` test for details. - // - // If the enum is declared as `#[non_exhaustive]`, we treat it as if it had an additionnal - // "unknown" constructor. However there is no point in enumerating all possible variants, - // because the user can't actually match against them themselves. So we return only the - // fictitious constructor. - // E.g., in an example like: - // ``` - // let err: io::ErrorKind = ...; - // match err { - // io::ErrorKind::NotFound => {}, - // } - // ``` - // we don't want to show every possible IO error, but instead have only `_` as the witness. - return vec![NonExhaustive]; - } - - ctors + } } /// An inclusive interval, used for precise integer exhaustiveness checking. From ec45882b42a07303ae3682898124ee8ae035baba Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 13 Nov 2019 00:35:57 +0900 Subject: [PATCH 21/35] Add test for issue-30904 --- src/test/ui/unboxed-closures/issue-30904.rs | 36 +++++++++++++++++++ .../ui/unboxed-closures/issue-30904.stderr | 24 +++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 src/test/ui/unboxed-closures/issue-30904.rs create mode 100644 src/test/ui/unboxed-closures/issue-30904.stderr diff --git a/src/test/ui/unboxed-closures/issue-30904.rs b/src/test/ui/unboxed-closures/issue-30904.rs new file mode 100644 index 0000000000000..eec5e962b431e --- /dev/null +++ b/src/test/ui/unboxed-closures/issue-30904.rs @@ -0,0 +1,36 @@ +#![feature(fn_traits, unboxed_closures)] + +fn test FnOnce<(&'x str,)>>(_: F) {} + +struct Compose(F,G); +impl FnOnce<(T,)> for Compose +where F: FnOnce<(T,)>, G: FnOnce<(F::Output,)> { + type Output = G::Output; + extern "rust-call" fn call_once(self, (x,): (T,)) -> G::Output { + (self.1)((self.0)(x)) + } +} + +struct Str<'a>(&'a str); +fn mk_str<'a>(s: &'a str) -> Str<'a> { Str(s) } + +fn main() { + let _: for<'a> fn(&'a str) -> Str<'a> = mk_str; + // expected concrete lifetime, found bound lifetime parameter 'a + let _: for<'a> fn(&'a str) -> Str<'a> = Str; + //~^ ERROR: mismatched types + + test(|_: &str| {}); + test(mk_str); + // expected concrete lifetime, found bound lifetime parameter 'x + test(Str); //~ ERROR: type mismatch in function arguments + + test(Compose(|_: &str| {}, |_| {})); + test(Compose(mk_str, |_| {})); + // internal compiler error: cannot relate bound region: + // ReLateBound(DebruijnIndex { depth: 2 }, + // BrNamed(DefId { krate: 0, node: DefIndex(6) => test::'x }, 'x(65))) + //<= ReSkolemized(0, + // BrNamed(DefId { krate: 0, node: DefIndex(6) => test::'x }, 'x(65))) + test(Compose(Str, |_| {})); +} diff --git a/src/test/ui/unboxed-closures/issue-30904.stderr b/src/test/ui/unboxed-closures/issue-30904.stderr new file mode 100644 index 0000000000000..943cbe0ccc297 --- /dev/null +++ b/src/test/ui/unboxed-closures/issue-30904.stderr @@ -0,0 +1,24 @@ +error[E0308]: mismatched types + --> $DIR/issue-30904.rs:20:45 + | +LL | let _: for<'a> fn(&'a str) -> Str<'a> = Str; + | ^^^ expected concrete lifetime, found bound lifetime parameter 'a + | + = note: expected type `for<'a> fn(&'a str) -> Str<'a>` + found type `fn(&str) -> Str<'_> {Str::<'_>}` + +error[E0631]: type mismatch in function arguments + --> $DIR/issue-30904.rs:26:10 + | +LL | fn test FnOnce<(&'x str,)>>(_: F) {} + | ---- -------------------------- required by this bound in `test` +... +LL | struct Str<'a>(&'a str); + | ------------------------ found signature of `fn(&str) -> _` +... +LL | test(Str); + | ^^^ expected signature of `for<'x> fn(&'x str) -> _` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From bae9832f714e7244bedc34eac40273eb6e915ed7 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 13 Nov 2019 00:36:20 +0900 Subject: [PATCH 22/35] Add test for issue-40231 --- src/test/ui/issues/issue-40231-1.rs | 54 +++++++++++++++++++++++++++++ src/test/ui/issues/issue-40231-2.rs | 54 +++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 src/test/ui/issues/issue-40231-1.rs create mode 100644 src/test/ui/issues/issue-40231-2.rs diff --git a/src/test/ui/issues/issue-40231-1.rs b/src/test/ui/issues/issue-40231-1.rs new file mode 100644 index 0000000000000..999399ec8d34c --- /dev/null +++ b/src/test/ui/issues/issue-40231-1.rs @@ -0,0 +1,54 @@ +// check-pass + +#![allow(dead_code)] + +trait Structure: Sized where E: Encoding { + type RefTarget: ?Sized; + type FfiPtr; + unsafe fn borrow_from_ffi_ptr<'a>(ptr: Self::FfiPtr) -> Option<&'a Self::RefTarget>; +} + +enum Slice {} + +impl Structure for Slice where E: Encoding { + type RefTarget = [E::Unit]; + type FfiPtr = (*const E::FfiUnit, usize); + unsafe fn borrow_from_ffi_ptr<'a>(_ptr: Self::FfiPtr) -> Option<&'a Self::RefTarget> { + panic!() + } +} + +trait Encoding { + type Unit: Unit; + type FfiUnit; +} + +trait Unit {} + +enum Utf16 {} + +impl Encoding for Utf16 { + type Unit = Utf16Unit; + type FfiUnit = u16; +} + +struct Utf16Unit(pub u16); + +impl Unit for Utf16Unit {} + +type SUtf16Str = SeStr; + +struct SeStr where S: Structure, E: Encoding { + _data: S::RefTarget, +} + +impl SeStr where S: Structure, E: Encoding { + pub unsafe fn from_ptr<'a>(_ptr: S::FfiPtr) -> Option<&'a Self> { + panic!() + } +} + +fn main() { + const TEXT_U16: &'static [u16] = &[]; + let _ = unsafe { SUtf16Str::from_ptr((TEXT_U16.as_ptr(), TEXT_U16.len())).unwrap() }; +} diff --git a/src/test/ui/issues/issue-40231-2.rs b/src/test/ui/issues/issue-40231-2.rs new file mode 100644 index 0000000000000..780433b28c596 --- /dev/null +++ b/src/test/ui/issues/issue-40231-2.rs @@ -0,0 +1,54 @@ +// check-pass + +#![allow(dead_code)] + +trait Structure: Sized where E: Encoding { + type RefTarget: ?Sized; + type FfiPtr; + unsafe fn borrow_from_ffi_ptr<'a>(ptr: Self::FfiPtr) -> Option<&'a Self::RefTarget>; +} + +enum Slice {} + +impl Structure for Slice where E: Encoding { + type RefTarget = [E::Unit]; + type FfiPtr = (*const E::FfiUnit, usize); + unsafe fn borrow_from_ffi_ptr<'a>(_ptr: Self::FfiPtr) -> Option<&'a Self::RefTarget> { + panic!() + } +} + +trait Encoding { + type Unit: Unit; + type FfiUnit; +} + +trait Unit {} + +enum Utf16 {} + +impl Encoding for Utf16 { + type Unit = Utf16Unit; + type FfiUnit = u16; +} + +struct Utf16Unit(pub u16); + +impl Unit for Utf16Unit {} + +struct SUtf16Str { + _data: >::RefTarget, +} + +impl SUtf16Str { + pub unsafe fn from_ptr<'a>(ptr: >::FfiPtr) + -> Option<&'a Self> { + std::mem::transmute::::Unit]>, _>( + >::borrow_from_ffi_ptr(ptr)) + } +} + +fn main() { + const TEXT_U16: &'static [u16] = &[]; + let _ = unsafe { SUtf16Str::from_ptr((TEXT_U16.as_ptr(), TEXT_U16.len())).unwrap() }; +} From 412f0006f520357d220882b57eef501999b44c9a Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 13 Nov 2019 00:36:38 +0900 Subject: [PATCH 23/35] Add test for issue-52432 --- src/test/ui/consts/issue-52432.rs | 10 ++++++++++ src/test/ui/consts/issue-52432.stderr | 28 +++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/test/ui/consts/issue-52432.rs create mode 100644 src/test/ui/consts/issue-52432.stderr diff --git a/src/test/ui/consts/issue-52432.rs b/src/test/ui/consts/issue-52432.rs new file mode 100644 index 0000000000000..2d4c939f47d79 --- /dev/null +++ b/src/test/ui/consts/issue-52432.rs @@ -0,0 +1,10 @@ +#![feature(const_raw_ptr_to_usize_cast)] + +fn main() { + [(); &(static |x| {}) as *const _ as usize]; + //~^ ERROR: closures cannot be static + //~| ERROR: type annotations needed + [(); &(static || {}) as *const _ as usize]; + //~^ ERROR: closures cannot be static + //~| ERROR: evaluation of constant value failed +} diff --git a/src/test/ui/consts/issue-52432.stderr b/src/test/ui/consts/issue-52432.stderr new file mode 100644 index 0000000000000..e9539d24118a0 --- /dev/null +++ b/src/test/ui/consts/issue-52432.stderr @@ -0,0 +1,28 @@ +error[E0697]: closures cannot be static + --> $DIR/issue-52432.rs:4:12 + | +LL | [(); &(static |x| {}) as *const _ as usize]; + | ^^^^^^^^^^ + +error[E0697]: closures cannot be static + --> $DIR/issue-52432.rs:7:12 + | +LL | [(); &(static || {}) as *const _ as usize]; + | ^^^^^^^^^ + +error[E0282]: type annotations needed + --> $DIR/issue-52432.rs:4:20 + | +LL | [(); &(static |x| {}) as *const _ as usize]; + | ^ consider giving this closure parameter a type + +error[E0080]: evaluation of constant value failed + --> $DIR/issue-52432.rs:7:10 + | +LL | [(); &(static || {}) as *const _ as usize]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0080, E0282, E0697. +For more information about an error, try `rustc --explain E0080`. From 74d45afbf5473d1b255629e786e074060dcc7ec2 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 13 Nov 2019 00:37:00 +0900 Subject: [PATCH 24/35] Add test for issue-63279 --- src/test/ui/type-alias-impl-trait/issue-63279.rs | 9 +++++++++ .../ui/type-alias-impl-trait/issue-63279.stderr | 13 +++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 src/test/ui/type-alias-impl-trait/issue-63279.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-63279.stderr diff --git a/src/test/ui/type-alias-impl-trait/issue-63279.rs b/src/test/ui/type-alias-impl-trait/issue-63279.rs new file mode 100644 index 0000000000000..586ff7a31587f --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-63279.rs @@ -0,0 +1,9 @@ +#![feature(type_alias_impl_trait)] + +type Closure = impl FnOnce(); //~ ERROR: type mismatch resolving + +fn c() -> Closure { + || -> Closure { || () } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-63279.stderr b/src/test/ui/type-alias-impl-trait/issue-63279.stderr new file mode 100644 index 0000000000000..a5065241fc74d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-63279.stderr @@ -0,0 +1,13 @@ +error[E0271]: type mismatch resolving `<[closure@$DIR/issue-63279.rs:6:5: 6:28] as std::ops::FnOnce<()>>::Output == ()` + --> $DIR/issue-63279.rs:3:1 + | +LL | type Closure = impl FnOnce(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found () + | + = note: expected type `Closure` + found type `()` + = note: the return type of a function must have a statically known size + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. From bfa5e5f788593f3395cac9ba14cdefa5afd5e465 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 12 Nov 2019 09:42:46 -0800 Subject: [PATCH 25/35] Fallback to the unmodified path in bindir_relative --- src/bootstrap/builder.rs | 3 +-- src/bootstrap/config.rs | 15 +++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 70b53cfc4e752..10d02d6db8299 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1232,8 +1232,7 @@ impl<'a> Builder<'a> { } // Try to use a sysroot-relative bindir, in case it was configured absolutely. - let bindir = self.config.bindir_relative().unwrap_or(&self.config.bindir); - cargo.env("RUSTC_INSTALL_BINDIR", bindir); + cargo.env("RUSTC_INSTALL_BINDIR", self.config.bindir_relative()); self.ci_env.force_coloring_in_ci(&mut cargo); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 2493167f2f5e5..0c03b95c7b251 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -647,15 +647,18 @@ impl Config { config } - /// Try to find the relative path of `bindir`. - pub fn bindir_relative(&self) -> Option<&Path> { + /// Try to find the relative path of `bindir`, otherwise return it in full. + pub fn bindir_relative(&self) -> &Path { let bindir = &self.bindir; - if bindir.is_relative() { - Some(bindir) - } else { + if bindir.is_absolute() { // Try to make it relative to the prefix. - bindir.strip_prefix(self.prefix.as_ref()?).ok() + if let Some(prefix) = &self.prefix { + if let Ok(stripped) = bindir.strip_prefix(prefix) { + return stripped; + } + } } + bindir } /// Try to find the relative path of `libdir`. From f696b21c5f1017ebb451d1e9d2d8fe261b26507f Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 11 Nov 2019 17:15:36 -0500 Subject: [PATCH 26/35] Move self-profile infrastructure to data structures The single dependency on queries (QueryName) can be fairly easily abstracted via a trait and this further decouples Session from librustc (the primary goal). --- Cargo.lock | 3 ++- src/librustc/Cargo.toml | 1 - src/librustc/lib.rs | 1 - src/librustc/session/mod.rs | 2 +- src/librustc/ty/context.rs | 2 +- src/librustc/ty/query/config.rs | 2 +- src/librustc/ty/query/mod.rs | 2 +- src/librustc/ty/query/plumbing.rs | 14 +++++++++-- src/librustc_codegen_ssa/back/write.rs | 2 +- src/librustc_data_structures/Cargo.toml | 2 ++ src/librustc_data_structures/lib.rs | 1 + .../profiling.rs | 24 ++++++++++--------- 12 files changed, 35 insertions(+), 21 deletions(-) rename src/{librustc/util => librustc_data_structures}/profiling.rs (93%) diff --git a/Cargo.lock b/Cargo.lock index 16f2ffc28150f..7c074fb18a6f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3120,7 +3120,6 @@ dependencies = [ "graphviz", "jobserver", "log", - "measureme", "num_cpus", "parking_lot 0.9.0", "polonius-engine", @@ -3470,6 +3469,7 @@ dependencies = [ name = "rustc_data_structures" version = "0.0.0" dependencies = [ + "bitflags", "cfg-if", "crossbeam-utils 0.6.5", "ena", @@ -3478,6 +3478,7 @@ dependencies = [ "jobserver", "lazy_static 1.3.0", "log", + "measureme", "parking_lot 0.9.0", "rustc-hash", "rustc-rayon 0.3.0", diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 92b94af75d750..bcbe765b85073 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -40,4 +40,3 @@ byteorder = { version = "1.3" } chalk-engine = { version = "0.9.0", default-features=false } rustc_fs_util = { path = "../librustc_fs_util" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } -measureme = "0.4" diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 996f5b1241263..1fd5bcb4915b8 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -126,7 +126,6 @@ pub mod util { pub mod captures; pub mod common; pub mod nodemap; - pub mod profiling; pub mod bug; } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 9792223ea1506..bba377392b433 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -29,11 +29,11 @@ use syntax::source_map; use syntax::sess::{ParseSess, ProcessCfgMod}; use syntax::symbol::Symbol; use syntax_pos::{MultiSpan, Span}; -use crate::util::profiling::{SelfProfiler, SelfProfilerRef}; use rustc_target::spec::{PanicStrategy, RelroLevel, Target, TargetTriple}; use rustc_data_structures::flock; use rustc_data_structures::jobserver; +use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef}; use ::jobserver::Client; use std; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 04e0f6f4b56d7..2ba670f509f80 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -46,11 +46,11 @@ use crate::ty::CanonicalPolyFnSig; use crate::util::common::ErrorReported; use crate::util::nodemap::{DefIdMap, DefIdSet, ItemLocalMap, ItemLocalSet, NodeMap}; use crate::util::nodemap::{FxHashMap, FxHashSet}; -use crate::util::profiling::SelfProfilerRef; use errors::DiagnosticBuilder; use arena::SyncDroplessArena; use smallvec::SmallVec; +use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::stable_hasher::{ HashStable, StableHasher, StableVec, hash_stable_hashmap, }; diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index c1c6a655d96a9..7e126459dcc73 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -6,7 +6,7 @@ use crate::ty::query::queries; use crate::ty::query::{Query, QueryName}; use crate::ty::query::QueryCache; use crate::ty::query::plumbing::CycleError; -use crate::util::profiling::ProfileCategory; +use rustc_data_structures::profiling::ProfileCategory; use std::borrow::Cow; use std::hash::Hash; diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 0615004125b3c..a1eb1c43335b1 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -39,7 +39,7 @@ use crate::ty::util::NeedsDrop; use crate::ty::subst::SubstsRef; use crate::util::nodemap::{DefIdSet, DefIdMap}; use crate::util::common::ErrorReported; -use crate::util::profiling::ProfileCategory::*; +use rustc_data_structures::profiling::ProfileCategory::*; use rustc_data_structures::svh::Svh; use rustc_index::vec::IndexVec; diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 538154b035ac6..0f77a637b4d03 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -672,7 +672,7 @@ macro_rules! define_queries_inner { rustc_data_structures::stable_hasher::StableHasher, ich::StableHashingContext }; - use crate::util::profiling::ProfileCategory; + use rustc_data_structures::profiling::ProfileCategory; define_queries_struct! { tcx: $tcx, @@ -816,8 +816,18 @@ macro_rules! define_queries_inner { $($name),* } + impl rustc_data_structures::profiling::QueryName for QueryName { + fn discriminant(self) -> std::mem::Discriminant { + std::mem::discriminant(&self) + } + + fn as_str(self) -> &'static str { + QueryName::as_str(&self) + } + } + impl QueryName { - pub fn register_with_profiler(profiler: &crate::util::profiling::SelfProfiler) { + pub fn register_with_profiler(profiler: &rustc_data_structures::profiling::SelfProfiler) { $(profiler.register_query_name(QueryName::$name);)* } diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index b302b9ae7f0e4..ed901fa064a4e 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -19,7 +19,7 @@ use rustc::util::nodemap::FxHashMap; use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::ty::TyCtxt; use rustc::util::common::{time_depth, set_time_depth, print_time_passes_entry}; -use rustc::util::profiling::SelfProfilerRef; +use rustc_data_structures::profiling::SelfProfilerRef; use rustc_fs_util::link_or_copy; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index e79b3a81b9654..0fd47115022c2 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -25,6 +25,8 @@ rayon-core = { version = "0.3.0", package = "rustc-rayon-core" } rustc-hash = "1.0.1" smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_index = { path = "../librustc_index", package = "rustc_index" } +bitflags = "1.2.1" +measureme = "0.4" [dependencies.parking_lot] version = "0.9" diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 474a42644d915..fb541637e5f79 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -94,6 +94,7 @@ pub use ena::unify; pub mod vec_linked_list; pub mod work_queue; pub mod fingerprint; +pub mod profiling; pub struct OnDrop(pub F); diff --git a/src/librustc/util/profiling.rs b/src/librustc_data_structures/profiling.rs similarity index 93% rename from src/librustc/util/profiling.rs rename to src/librustc_data_structures/profiling.rs index 5a1b7f3aa4cb8..b89170cccdb70 100644 --- a/src/librustc/util/profiling.rs +++ b/src/librustc_data_structures/profiling.rs @@ -7,8 +7,6 @@ use std::sync::Arc; use std::thread::ThreadId; use std::u32; -use crate::ty::query::QueryName; - use measureme::{StringId, TimestampKind}; /// MmapSerializatioSink is faster on macOS and Linux @@ -20,6 +18,10 @@ type SerializationSink = measureme::FileSerializationSink; type Profiler = measureme::Profiler; +pub trait QueryName: Sized + Copy { + fn discriminant(self) -> Discriminant; + fn as_str(self) -> &'static str; +} #[derive(Clone, Copy, Debug, PartialEq, Eq, Ord, PartialOrd)] pub enum ProfileCategory { @@ -32,7 +34,7 @@ pub enum ProfileCategory { Other, } -bitflags! { +bitflags::bitflags! { struct EventFilter: u32 { const GENERIC_ACTIVITIES = 1 << 0; const QUERY_PROVIDERS = 1 << 1; @@ -137,7 +139,7 @@ impl SelfProfilerRef { /// Start profiling a query provider. Profiling continues until the /// TimingGuard returned from this call is dropped. #[inline(always)] - pub fn query_provider(&self, query_name: QueryName) -> TimingGuard<'_> { + pub fn query_provider(&self, query_name: impl QueryName) -> TimingGuard<'_> { self.exec(EventFilter::QUERY_PROVIDERS, |profiler| { let event_id = SelfProfiler::get_query_name_string_id(query_name); TimingGuard::start(profiler, profiler.query_event_kind, event_id) @@ -146,7 +148,7 @@ impl SelfProfilerRef { /// Record a query in-memory cache hit. #[inline(always)] - pub fn query_cache_hit(&self, query_name: QueryName) { + pub fn query_cache_hit(&self, query_name: impl QueryName) { self.non_guard_query_event( |profiler| profiler.query_cache_hit_event_kind, query_name, @@ -159,7 +161,7 @@ impl SelfProfilerRef { /// Profiling continues until the TimingGuard returned from this call is /// dropped. #[inline(always)] - pub fn query_blocked(&self, query_name: QueryName) -> TimingGuard<'_> { + pub fn query_blocked(&self, query_name: impl QueryName) -> TimingGuard<'_> { self.exec(EventFilter::QUERY_BLOCKED, |profiler| { let event_id = SelfProfiler::get_query_name_string_id(query_name); TimingGuard::start(profiler, profiler.query_blocked_event_kind, event_id) @@ -170,7 +172,7 @@ impl SelfProfilerRef { /// incremental compilation on-disk cache. Profiling continues until the /// TimingGuard returned from this call is dropped. #[inline(always)] - pub fn incr_cache_loading(&self, query_name: QueryName) -> TimingGuard<'_> { + pub fn incr_cache_loading(&self, query_name: impl QueryName) -> TimingGuard<'_> { self.exec(EventFilter::INCR_CACHE_LOADS, |profiler| { let event_id = SelfProfiler::get_query_name_string_id(query_name); TimingGuard::start( @@ -185,7 +187,7 @@ impl SelfProfilerRef { fn non_guard_query_event( &self, event_kind: fn(&SelfProfiler) -> StringId, - query_name: QueryName, + query_name: impl QueryName, event_filter: EventFilter, timestamp_kind: TimestampKind ) { @@ -274,15 +276,15 @@ impl SelfProfiler { }) } - fn get_query_name_string_id(query_name: QueryName) -> StringId { + fn get_query_name_string_id(query_name: impl QueryName) -> StringId { let discriminant = unsafe { - mem::transmute::, u64>(mem::discriminant(&query_name)) + mem::transmute::, u64>(query_name.discriminant()) }; StringId::reserved(discriminant as u32) } - pub fn register_query_name(&self, query_name: QueryName) { + pub fn register_query_name(&self, query_name: impl QueryName) { let id = SelfProfiler::get_query_name_string_id(query_name); self.profiler.alloc_string_with_reserved_id(id, query_name.as_str()); } From 8c29b74b15d494fd963109bade5f31a0ada431d0 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 12 Nov 2019 11:20:01 -0500 Subject: [PATCH 27/35] Remove dead code for encoding/decoding lint IDs This helps decouple the lint system from needing the implicit TLS TyCtxt as well. --- src/librustc/lint/context.rs | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 721baad25639f..dc3bc5fa0cebf 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -35,7 +35,6 @@ use crate::util::common::time; use errors::DiagnosticBuilder; use std::slice; use rustc_data_structures::sync::{self, ParallelIterator, join, par_iter}; -use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use syntax::ast; use syntax::util::lev_distance::find_best_match_for_name; use syntax::visit as ast_visit; @@ -71,7 +70,7 @@ pub struct LintStore { /// Lints that are buffered up early on in the `Session` before the /// `LintLevels` is calculated -#[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)] +#[derive(PartialEq, Debug)] pub struct BufferedEarlyLint { pub lint_id: LintId, pub ast_id: ast::NodeId, @@ -1574,27 +1573,3 @@ pub fn check_ast_crate( } } } - -impl Encodable for LintId { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_str(&self.lint.name.to_lowercase()) - } -} - -impl Decodable for LintId { - #[inline] - fn decode(d: &mut D) -> Result { - let s = d.read_str()?; - ty::tls::with(|tcx| { - match tcx.lint_store.find_lints(&s) { - Ok(ids) => { - if ids.len() != 0 { - panic!("invalid lint-id `{}`", s); - } - Ok(ids[0]) - } - Err(_) => panic!("invalid lint-id `{}`", s), - } - }) - } -} From 2fd545485aea36d0dcb403375218fd801f4a2ca8 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 12 Nov 2019 11:44:01 -0500 Subject: [PATCH 28/35] Register queries with self profiler in rustc_interface --- src/librustc/session/mod.rs | 1 - src/librustc/ty/query/plumbing.rs | 4 +++- src/librustc_data_structures/profiling.rs | 6 ++++++ src/librustc_interface/util.rs | 4 ++++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index bba377392b433..cedac74d774a8 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -1099,7 +1099,6 @@ fn build_session_( ); match profiler { Ok(profiler) => { - crate::ty::query::QueryName::register_with_profiler(&profiler); Some(Arc::new(profiler)) }, Err(e) => { diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 0f77a637b4d03..1c15b7d5f3559 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -827,7 +827,9 @@ macro_rules! define_queries_inner { } impl QueryName { - pub fn register_with_profiler(profiler: &rustc_data_structures::profiling::SelfProfiler) { + pub fn register_with_profiler( + profiler: &rustc_data_structures::profiling::SelfProfiler, + ) { $(profiler.register_query_name(QueryName::$name);)* } diff --git a/src/librustc_data_structures/profiling.rs b/src/librustc_data_structures/profiling.rs index b89170cccdb70..86f59bfabe627 100644 --- a/src/librustc_data_structures/profiling.rs +++ b/src/librustc_data_structures/profiling.rs @@ -205,6 +205,12 @@ impl SelfProfilerRef { TimingGuard::none() })); } + + pub fn register_queries(&self, f: impl FnOnce(&SelfProfiler)) { + if let Some(profiler) = &self.profiler { + f(&profiler) + } + } } pub struct SelfProfiler { diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 115345955aea3..6b9d708cefaca 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -108,6 +108,10 @@ pub fn create_session( process_configure_mod, ); + sess.prof.register_queries(|profiler| { + rustc::ty::query::QueryName::register_with_profiler(&profiler); + }); + let codegen_backend = get_codegen_backend(&sess); let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg)); From 6a3a05580ee5d6f807f87013871b568eab6a55c3 Mon Sep 17 00:00:00 2001 From: Dylan DPC Date: Wed, 13 Nov 2019 01:47:25 +0100 Subject: [PATCH 29/35] Update error_codes.rs --- src/librustc/error_codes.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index 9274608bc2f84..dab8fd565facc 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -1912,15 +1912,17 @@ fn bar<'short, 'long>(c: Foo<'short>, l: &'long isize) { ``` In this example, we tried to set a value with an incompatible lifetime to -another one (`'long` != `'short`). We can solve this issue in two different -ways: either we make `'short` lives longer than `'long`: +another one (`'long` is unrelated to `'short`). We can solve this issue in two different +ways: + +Either we make `'short` live at least as long as `'long`: ``` struct Foo<'a> { x: &'a isize, } -// we set 'short to outlive 'long +// we set 'short to live at least as long as 'long fn bar<'short: 'long, 'long>(c: Foo<'short>, l: &'long isize) { let _: Foo<'long> = c; // ok! } From 1de094a28e1b648553e5ab3c84b8336a1d2f26ad Mon Sep 17 00:00:00 2001 From: Dylan DPC Date: Wed, 13 Nov 2019 01:50:12 +0100 Subject: [PATCH 30/35] Update error_codes.rs From fd868d4bf4d0be79b7bb0c38145faecb18f18217 Mon Sep 17 00:00:00 2001 From: Dylan DPC Date: Wed, 13 Nov 2019 02:16:01 +0100 Subject: [PATCH 31/35] tidy up! --- src/librustc/error_codes.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index dab8fd565facc..a7a66fd7cd786 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -1912,8 +1912,8 @@ fn bar<'short, 'long>(c: Foo<'short>, l: &'long isize) { ``` In this example, we tried to set a value with an incompatible lifetime to -another one (`'long` is unrelated to `'short`). We can solve this issue in two different -ways: +another one (`'long` is unrelated to `'short`). We can solve this issue in +two different ways: Either we make `'short` live at least as long as `'long`: From aba385abbd69146387893c84951a06ec283f4d10 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 13 Nov 2019 09:05:57 +0100 Subject: [PATCH 32/35] Trailing full stop Co-Authored-By: Mazdak Farrokhzad --- src/libcore/cell.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 0860d9c0cfa8b..e3292ecc1d187 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1554,7 +1554,7 @@ impl UnsafeCell { /// This can be cast to a pointer of any kind. /// Ensure that the access is unique (no active references, mutable or not) /// when casting to `&mut T`, and ensure that there are no mutations - /// or mutable aliases going on when casting to `&T` + /// or mutable aliases going on when casting to `&T`. /// /// # Examples /// From 19ebe2fb6d7de19de155e70938fafcca6f9b5003 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 13 Nov 2019 09:07:52 +0100 Subject: [PATCH 33/35] clarify why we can do the ptr cast --- src/libcore/cell.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index e3292ecc1d187..4afeec6675865 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1545,7 +1545,8 @@ impl UnsafeCell { #[stable(feature = "rust1", since = "1.0.0")] pub const fn get(&self) -> *mut T { // We can just cast the pointer from `UnsafeCell` to `T` because of - // #[repr(transparent)] + // #[repr(transparent)]. This exploits libstd's special status, there is + // no guarantee for user code that this will work in future versions of the compiler! self as *const UnsafeCell as *const T as *mut T } @@ -1572,10 +1573,11 @@ impl UnsafeCell { /// assert_eq!(uc.into_inner(), 5); /// ``` #[inline] - #[unstable(feature = "unsafe_cell_raw_get", issue = "0")] + #[unstable(feature = "unsafe_cell_raw_get", issue = "66358")] pub const fn raw_get(self: *const Self) -> *mut T { // We can just cast the pointer from `UnsafeCell` to `T` because of - // #[repr(transparent)] + // #[repr(transparent)]. This exploits libstd's special status, there is + // no guarantee for user code that this will work in future versions of the compiler! self as *const T as *mut T } } From 5b5ae01340fdbb31f56453655472b783e5719eb9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 13 Nov 2019 09:11:09 +0100 Subject: [PATCH 34/35] expand docs --- src/libcore/cell.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 4afeec6675865..7b7be8f3d2ff6 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1551,15 +1551,20 @@ impl UnsafeCell { } /// Gets a mutable pointer to the wrapped value. + /// The difference to [`get`] is that this function accepts a raw pointer, + /// which is useful to avoid the creation of temporary references. /// - /// This can be cast to a pointer of any kind. + /// The result can be cast to a pointer of any kind. /// Ensure that the access is unique (no active references, mutable or not) /// when casting to `&mut T`, and ensure that there are no mutations /// or mutable aliases going on when casting to `&T`. /// + /// [`get`]: #method.get + /// /// # Examples /// - /// Gradual initialization of an `UnsafeCell`: + /// Gradual initialization of an `UnsafeCell` requires `raw_get`, as + /// calling `get` would require creating a reference to uninitialized data: /// /// ``` /// #![feature(unsafe_cell_raw_get)] From 861698a493fc547254e61dc23a43dfb0683df91a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 13 Nov 2019 09:31:08 +0100 Subject: [PATCH 35/35] make things ugly --- src/libcore/cell.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 7b7be8f3d2ff6..03f32e726187b 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1572,18 +1572,18 @@ impl UnsafeCell { /// use std::mem::MaybeUninit; /// /// let m = MaybeUninit::>::uninit(); - /// unsafe { m.as_ptr().raw_get().write(5); } + /// unsafe { UnsafeCell::raw_get(m.as_ptr()).write(5); } /// let uc = unsafe { m.assume_init() }; /// /// assert_eq!(uc.into_inner(), 5); /// ``` #[inline] #[unstable(feature = "unsafe_cell_raw_get", issue = "66358")] - pub const fn raw_get(self: *const Self) -> *mut T { + pub const fn raw_get(this: *const Self) -> *mut T { // We can just cast the pointer from `UnsafeCell` to `T` because of // #[repr(transparent)]. This exploits libstd's special status, there is // no guarantee for user code that this will work in future versions of the compiler! - self as *const T as *mut T + this as *const T as *mut T } }