diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff4fa1527e93a..78ff874e75501 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -404,6 +404,7 @@ jobs: RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --host=aarch64-pc-windows-msvc --enable-full-tools --enable-profiler" SCRIPT: python x.py dist DIST_REQUIRE_ALL_TOOLS: 0 + WINDOWS_SDK_20348_HACK: 1 os: windows-latest-xl - name: dist-i686-mingw env: diff --git a/RELEASES.md b/RELEASES.md index 2124195bcb209..c0851a1506e13 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -10,8 +10,7 @@ Language Compiler -------- -- [Added tier 3\* support for `powerpc-unknown-freebsd`.][87370] -- [Added tier 3 support for `powerpc64le-unknown-freebsd`.][83572] +- [Added tier 3\* support for `powerpc64le-unknown-freebsd`.][83572] \* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. @@ -24,17 +23,6 @@ Libraries no longer reject certain valid floating point values, and reduce the produced code size for non-stripped artifacts. - [`string::Drain` now implements `AsRef` and `AsRef<[u8]>`.][86858] -- [`collections::{BinaryHeap, BTreeSet, HashSet, LinkedList, VecDeque}` now - implement `From<[T; N]>`.][84111] -- [`collections::{BTreeMap, HashMap}` now implement `From<[(K, V); N]>`.][84111] - This allows you to write the following; - ```rust - let highscores = std::collections::HashMap::from([ - ("Alice", 9000u32), - ("Bob", 7250), - ("Charlie", 5500), - ]); - ``` Stabilised APIs --------------- @@ -60,7 +48,6 @@ Stabilised APIs The following previously stable functions are now `const`. - [`str::from_utf8_unchecked`] -- [`mem::transmute`] Cargo @@ -131,7 +118,6 @@ Compatibility Notes [`MaybeUninit::assume_init_ref`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init_ref [`MaybeUninit::write`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.write [`Seek::rewind`]: https://doc.rust-lang.org/stable/std/io/trait.Seek.html#method.rewind -[`mem::transmute`]: https://doc.rust-lang.org/stable/std/mem/fn.transmute.html [`ops::ControlFlow`]: https://doc.rust-lang.org/stable/std/ops/enum.ControlFlow.html [`str::from_utf8_unchecked`]: https://doc.rust-lang.org/stable/std/str/fn.from_utf8_unchecked.html [`x86::_bittest`]: https://doc.rust-lang.org/stable/core/arch/x86/fn._bittest.html diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 702f69a9fcf0b..53b99a14f379d 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -399,7 +399,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; + // This restriction needs to be applied after we have handled adjustments for `move` + // closures. We want to make sure any adjustment that might make us move the place into + // the closure gets handled. + let (place, capture_kind) = + restrict_precision_for_drop_types(self, place, capture_kind, usage_span); + capture_info.capture_kind = capture_kind; + let capture_info = if let Some(existing) = processed.get(&place) { determine_capture_info(*existing, capture_info) } else { @@ -626,7 +633,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.struct_span_lint_hir( lint::builtin::RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES, closure_hir_id, - closure_head_span, + closure_head_span, |lint| { let mut diagnostics_builder = lint.build( format!( @@ -1852,6 +1859,31 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> { self.borrow(assignee_place, diag_expr_id, ty::BorrowKind::MutBorrow); } } + +/// Rust doesn't permit moving fields out of a type that implements drop +fn restrict_precision_for_drop_types<'a, 'tcx>( + fcx: &'a FnCtxt<'a, 'tcx>, + mut place: Place<'tcx>, + mut curr_mode: ty::UpvarCapture<'tcx>, + span: Span, +) -> (Place<'tcx>, ty::UpvarCapture<'tcx>) { + let is_copy_type = fcx.infcx.type_is_copy_modulo_regions(fcx.param_env, place.ty(), span); + + if let (false, UpvarCapture::ByValue(..)) = (is_copy_type, curr_mode) { + for i in 0..place.projections.len() { + match place.ty_before_projection(i).kind() { + ty::Adt(def, _) if def.destructor(fcx.tcx).is_some() => { + truncate_place_to_len_and_update_capture_kind(&mut place, &mut curr_mode, i); + break; + } + _ => {} + } + } + } + + (place, curr_mode) +} + /// Truncate `place` so that an `unsafe` block isn't required to capture it. /// - No projections are applied to raw pointers, since these require unsafe blocks. We capture /// them completely. diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 6417f5a984ad5..c9f8692d41887 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -635,6 +635,9 @@ jobs: SCRIPT: python x.py dist # RLS does not build for aarch64-pc-windows-msvc. See rust-lang/rls#1693 DIST_REQUIRE_ALL_TOOLS: 0 + # Hack around this SDK version, because it doesn't work with clang. + # See https://github.com/rust-lang/rust/issues/88796 + WINDOWS_SDK_20348_HACK: 1 <<: *job-windows-xl - name: dist-i686-mingw diff --git a/src/ci/scripts/install-clang.sh b/src/ci/scripts/install-clang.sh index 7b540b5c6e99d..fd29d3a022ad3 100755 --- a/src/ci/scripts/install-clang.sh +++ b/src/ci/scripts/install-clang.sh @@ -37,6 +37,12 @@ if isMacOS; then # `clang-ar` by accident. ciCommandSetEnv AR "ar" elif isWindows && [[ ${CUSTOM_MINGW-0} -ne 1 ]]; then + + if [[ ${WINDOWS_SDK_20348_HACK-0} -eq 1 ]]; then + rm -rf '/c/Program Files (x86)/Windows Kits/10/include/10.0.20348.0' + mv '/c/Program Files (x86)/Windows Kits/10/include/'10.0.{19041,20348}.0 + fi + # If we're compiling for MSVC then we, like most other distribution builders, # switch to clang as the compiler. This'll allow us eventually to enable LTO # amongst LLVM and rustc. Note that we only do this on MSVC as I don't think diff --git a/src/stage0.txt b/src/stage0.txt index 6b1507e365036..24a67c4db8c18 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -12,8 +12,8 @@ # stable release's version number. `date` is the date where the release we're # bootstrapping off was released. -date: 2021-07-29 -rustc: beta +date: 2021-09-09 +rustc: 1.55.0 # We use a nightly rustfmt to format the source because it solves some # bootstrapping issues with use of new syntax in this repo. If you're looking at diff --git a/src/test/debuginfo/basic-types.rs b/src/test/debuginfo/basic-types.rs index c35c32554983a..d300e374bec90 100644 --- a/src/test/debuginfo/basic-types.rs +++ b/src/test/debuginfo/basic-types.rs @@ -9,6 +9,10 @@ // This fails on lldb 6.0.1 on x86-64 Fedora 28; so ignore Linux for now. // ignore-linux +// This started failing in windows too. See https://github.com/rust-lang/rust/issues/88796 +// FIXME: fix and unignore this on windows +// ignore-windows + // compile-flags:-g // === GDB TESTS =================================================================================== diff --git a/src/test/debuginfo/msvc-pretty-enums.rs b/src/test/debuginfo/msvc-pretty-enums.rs index 9463f82c79749..67b5da510f843 100644 --- a/src/test/debuginfo/msvc-pretty-enums.rs +++ b/src/test/debuginfo/msvc-pretty-enums.rs @@ -2,6 +2,10 @@ // ignore-tidy-linelength // compile-flags:-g +// This started failing recently. See https://github.com/rust-lang/rust/issues/88796 +// FIXME: fix and unignore this +// ignore-windows + // cdb-command: g // Note: The natvis used to visualize niche-layout enums don't work correctly in cdb diff --git a/src/test/debuginfo/pretty-std.rs b/src/test/debuginfo/pretty-std.rs index baeada69d1c9a..cb2e6c618b1ab 100644 --- a/src/test/debuginfo/pretty-std.rs +++ b/src/test/debuginfo/pretty-std.rs @@ -6,6 +6,10 @@ // min-lldb-version: 310 // min-cdb-version: 10.0.18317.1001 +// This started failing recently. See https://github.com/rust-lang/rust/issues/88796 +// FIXME: fix and unignore this +// ignore-windows + // === GDB TESTS =================================================================================== // gdb-command: run diff --git a/src/test/ui/closures/2229_closure_analysis/issue-88476.rs b/src/test/ui/closures/2229_closure_analysis/issue-88476.rs new file mode 100644 index 0000000000000..f5906d306007e --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/issue-88476.rs @@ -0,0 +1,62 @@ +// edition:2021 + +#![feature(rustc_attrs)] + +// Test that we can't move out of struct that impls `Drop`. + + +use std::rc::Rc; + +// Test that we restrict precision when moving not-`Copy` types, if any of the parent paths +// implement `Drop`. This is to ensure that we don't move out of a type that implements Drop. +pub fn test1() { + struct Foo(Rc); + + impl Drop for Foo { + fn drop(self: &mut Foo) {} + } + + let f = Foo(Rc::new(1)); + let x = #[rustc_capture_analysis] move || { + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 + //~| ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + println!("{:?}", f.0); + //~^ NOTE: Capturing f[(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture f[] -> ByValue + }; + + x(); +} + +// Test that we don't restrict precision when moving `Copy` types(i.e. when copying), +// even if any of the parent paths implement `Drop`. +fn test2() { + struct Character { + hp: u32, + name: String, + } + + impl Drop for Character { + fn drop(&mut self) {} + } + + let character = Character { hp: 100, name: format!("A") }; + + let c = #[rustc_capture_analysis] move || { + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 + //~| ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + println!("{}", character.hp) + //~^ NOTE: Capturing character[(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture character[(0, 0)] -> ByValue + }; + + c(); + + println!("{}", character.name); +} + +fn main() {} diff --git a/src/test/ui/closures/2229_closure_analysis/issue-88476.stderr b/src/test/ui/closures/2229_closure_analysis/issue-88476.stderr new file mode 100644 index 0000000000000..c7c9ecbbb0e8e --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/issue-88476.stderr @@ -0,0 +1,97 @@ +error[E0658]: attributes on expressions are experimental + --> $DIR/issue-88476.rs:20:13 + | +LL | let x = #[rustc_capture_analysis] move || { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + +error[E0658]: attributes on expressions are experimental + --> $DIR/issue-88476.rs:47:13 + | +LL | let c = #[rustc_capture_analysis] move || { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + +error: First Pass analysis includes: + --> $DIR/issue-88476.rs:20:39 + | +LL | let x = #[rustc_capture_analysis] move || { + | _______________________________________^ +LL | | +LL | | +LL | | +... | +LL | | +LL | | }; + | |_____^ + | +note: Capturing f[(0, 0)] -> ImmBorrow + --> $DIR/issue-88476.rs:25:26 + | +LL | println!("{:?}", f.0); + | ^^^ + +error: Min Capture analysis includes: + --> $DIR/issue-88476.rs:20:39 + | +LL | let x = #[rustc_capture_analysis] move || { + | _______________________________________^ +LL | | +LL | | +LL | | +... | +LL | | +LL | | }; + | |_____^ + | +note: Min Capture f[] -> ByValue + --> $DIR/issue-88476.rs:25:26 + | +LL | println!("{:?}", f.0); + | ^^^ + +error: First Pass analysis includes: + --> $DIR/issue-88476.rs:47:39 + | +LL | let c = #[rustc_capture_analysis] move || { + | _______________________________________^ +LL | | +LL | | +LL | | +... | +LL | | +LL | | }; + | |_____^ + | +note: Capturing character[(0, 0)] -> ImmBorrow + --> $DIR/issue-88476.rs:52:24 + | +LL | println!("{}", character.hp) + | ^^^^^^^^^^^^ + +error: Min Capture analysis includes: + --> $DIR/issue-88476.rs:47:39 + | +LL | let c = #[rustc_capture_analysis] move || { + | _______________________________________^ +LL | | +LL | | +LL | | +... | +LL | | +LL | | }; + | |_____^ + | +note: Min Capture character[(0, 0)] -> ByValue + --> $DIR/issue-88476.rs:52:24 + | +LL | println!("{}", character.hp) + | ^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/issue-88476.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/issue-88476.rs new file mode 100644 index 0000000000000..f44c2af803bcb --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/issue-88476.rs @@ -0,0 +1,47 @@ +// check-pass +// edition:2021 + +use std::rc::Rc; + +// Test that we restrict precision when moving not-`Copy` types, if any of the parent paths +// implement `Drop`. This is to ensure that we don't move out of a type that implements Drop. +pub fn test1() { + struct Foo(Rc); + + impl Drop for Foo { + fn drop(self: &mut Foo) {} + } + + let f = Foo(Rc::new(1)); + let x = move || { + println!("{:?}", f.0); + }; + + x(); +} + + +// Test that we don't restrict precision when moving `Copy` types(i.e. when copying), +// even if any of the parent paths implement `Drop`. +pub fn test2() { + struct Character { + hp: u32, + name: String, + } + + impl Drop for Character { + fn drop(&mut self) {} + } + + let character = Character { hp: 100, name: format!("A") }; + + let c = move || { + println!("{}", character.hp) + }; + + c(); + + println!("{}", character.name); +} + +fn main() {} diff --git a/src/tools/cargo b/src/tools/cargo index 18751dd3f238d..d199d817e4bb7 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 18751dd3f238d94d384a7fe967abfac06cbfe0b9 +Subproject commit d199d817e4bb70facc710716e73b5dddf80bc055