From f2dd585e6433f53c301990b47582d27db9453b84 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 20 Sep 2022 16:39:39 +0000 Subject: [PATCH 01/13] Better binder treatment (cherry picked from commit 83e6128b577649384ef4bd137223bcffe5c8a5b0) --- .../src/infer/error_reporting/mod.rs | 2 +- src/test/ui/suggestions/issue-101984.rs | 27 +++++++++++++++++++ src/test/ui/suggestions/issue-101984.stderr | 14 ++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/suggestions/issue-101984.rs create mode 100644 src/test/ui/suggestions/issue-101984.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 67526c2228937..eb5afe828119c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2765,7 +2765,7 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> { where T: relate::Relate<'tcx>, { - Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?)) + Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?)) } fn consts( diff --git a/src/test/ui/suggestions/issue-101984.rs b/src/test/ui/suggestions/issue-101984.rs new file mode 100644 index 0000000000000..5f7ecb77e0ed4 --- /dev/null +++ b/src/test/ui/suggestions/issue-101984.rs @@ -0,0 +1,27 @@ +use std::marker::PhantomData; + +type Component = fn(&()); + +struct Wrapper { + router: Router<(Component, Box)>, +} + +struct Match(PhantomData); + +struct Router(PhantomData); + +impl Router { + pub fn at(&self) -> Result, ()> { + todo!() + } +} + +impl Wrapper { + fn at(&self, path: &str) -> Result<(Component, Box), ()> { + let (cmp, router) = self.router.at()?; + //~^ ERROR mismatched types + todo!() + } +} + +fn main() {} diff --git a/src/test/ui/suggestions/issue-101984.stderr b/src/test/ui/suggestions/issue-101984.stderr new file mode 100644 index 0000000000000..c744c62d11f9b --- /dev/null +++ b/src/test/ui/suggestions/issue-101984.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/issue-101984.rs:21:13 + | +LL | let (cmp, router) = self.router.at()?; + | ^^^^^^^^^^^^^ ----------------- this expression has type `Match<&(for<'r> fn(&'r ()), Box)>` + | | + | expected struct `Match`, found tuple + | + = note: expected struct `Match<&(for<'r> fn(&'r ()), Box)>` + found tuple `(_, _)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From 45b953a09d5fa3227a9820fddddde5d224980ad3 Mon Sep 17 00:00:00 2001 From: Urgau Date: Wed, 21 Sep 2022 19:01:49 +0200 Subject: [PATCH 02/13] Add missing space between notable trait tooltip and where clause (cherry picked from commit e214385a4d1933ddb6a4c6ffeed50c7228674656) --- src/librustdoc/html/format.rs | 2 +- .../rustdoc/where.SWhere_TraitWhere_item-decl.html | 7 ++++++- src/test/rustdoc/where.rs | 12 ++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index ec6b8c2469c59..b499e186cc046 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -371,7 +371,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( format!("
where{where_preds}") } else { let mut clause = br_with_padding; - clause.truncate(clause.len() - 5 * " ".len()); + clause.truncate(clause.len() - 4 * " ".len()); write!(clause, "where{where_preds}")?; clause } diff --git a/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html b/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html index 54026ff034e00..542a3337bef0e 100644 --- a/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html +++ b/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html @@ -1,3 +1,8 @@
pub trait TraitWhere {
-    type Item<'a>
    where
        Self: 'a
; + type Item<'a>
    where
        Self: 'a
; + + fn func(self)
    where
        Self: Sized
, + { ... } + fn lines(self) -> Lines<Self>
    where
        Self: Sized
, + { ... } }
\ No newline at end of file diff --git a/src/test/rustdoc/where.rs b/src/test/rustdoc/where.rs index b1034c707f55a..7a6c0db237bfc 100644 --- a/src/test/rustdoc/where.rs +++ b/src/test/rustdoc/where.rs @@ -1,5 +1,7 @@ #![crate_name = "foo"] +use std::io::Lines; + pub trait MyTrait { fn dummy(&self) { } } // @has foo/struct.Alpha.html '//pre' "pub struct Alpha(_)where A: MyTrait" @@ -29,6 +31,16 @@ where // @snapshot SWhere_TraitWhere_item-decl - '//div[@class="docblock item-decl"]' pub trait TraitWhere { type Item<'a> where Self: 'a; + + fn func(self) + where + Self: Sized + {} + + fn lines(self) -> Lines + where + Self: Sized, + { todo!() } } // @has foo/struct.Echo.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ From de7a6e5b3ee8be57c115d13f261a039c94523ebc Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Thu, 6 Oct 2022 20:09:54 -0400 Subject: [PATCH 03/13] Avoid defensive re-initialization of the BufReader buffer (cherry picked from commit 95ae993bd86b97aff9a27498f2187fef431cab58) --- library/std/src/io/buffered/bufreader.rs | 8 +++++++ .../std/src/io/buffered/bufreader/buffer.rs | 19 ++++++++++++--- library/std/src/io/buffered/tests.rs | 24 +++++++++++++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs index 88ad92d8a9859..4f339a18a480e 100644 --- a/library/std/src/io/buffered/bufreader.rs +++ b/library/std/src/io/buffered/bufreader.rs @@ -224,6 +224,14 @@ impl BufReader { } } +// This is only used by a test which asserts that the initialization-tracking is correct. +#[cfg(test)] +impl BufReader { + pub fn initialized(&self) -> usize { + self.buf.initialized() + } +} + impl BufReader { /// Seeks relative to the current position. If the new position lies within the buffer, /// the buffer will not be flushed, allowing for more efficient seeks. diff --git a/library/std/src/io/buffered/bufreader/buffer.rs b/library/std/src/io/buffered/bufreader/buffer.rs index 867c22c6041e7..e9e29d60ca282 100644 --- a/library/std/src/io/buffered/bufreader/buffer.rs +++ b/library/std/src/io/buffered/bufreader/buffer.rs @@ -20,13 +20,19 @@ pub struct Buffer { // Each call to `fill_buf` sets `filled` to indicate how many bytes at the start of `buf` are // initialized with bytes from a read. filled: usize, + // This is the max number of bytes returned across all `fill_buf` calls. We track this so that we + // can accurately tell `read_buf` how many bytes of buf are initialized, to bypass as much of its + // defensive initialization as possible. Note that while this often the same as `filled`, it + // doesn't need to be. Calls to `fill_buf` are not required to actually fill the buffer, and + // omitting this is a huge perf regression for `Read` impls that do not. + initialized: usize, } impl Buffer { #[inline] pub fn with_capacity(capacity: usize) -> Self { let buf = Box::new_uninit_slice(capacity); - Self { buf, pos: 0, filled: 0 } + Self { buf, pos: 0, filled: 0, initialized: 0 } } #[inline] @@ -51,6 +57,12 @@ impl Buffer { self.pos } + // This is only used by a test which asserts that the initialization-tracking is correct. + #[cfg(test)] + pub fn initialized(&self) -> usize { + self.initialized + } + #[inline] pub fn discard_buffer(&mut self) { self.pos = 0; @@ -96,13 +108,14 @@ impl Buffer { let mut buf = BorrowedBuf::from(&mut *self.buf); // SAFETY: `self.filled` bytes will always have been initialized. unsafe { - buf.set_init(self.filled); + buf.set_init(self.initialized); } reader.read_buf(buf.unfilled())?; - self.filled = buf.len(); self.pos = 0; + self.filled = buf.len(); + self.initialized = buf.init_len(); } Ok(self.buffer()) } diff --git a/library/std/src/io/buffered/tests.rs b/library/std/src/io/buffered/tests.rs index bd6d95242ad94..f4e688eb926cc 100644 --- a/library/std/src/io/buffered/tests.rs +++ b/library/std/src/io/buffered/tests.rs @@ -1039,3 +1039,27 @@ fn single_formatted_write() { writeln!(&mut writer, "{}, {}!", "hello", "world").unwrap(); assert_eq!(writer.get_ref().events, [RecordedEvent::Write("hello, world!\n".to_string())]); } + +#[test] +fn bufreader_full_initialize() { + struct OneByteReader; + impl Read for OneByteReader { + fn read(&mut self, buf: &mut [u8]) -> crate::io::Result { + if buf.len() > 0 { + buf[0] = 0; + Ok(1) + } else { + Ok(0) + } + } + } + let mut reader = BufReader::new(OneByteReader); + // Nothing is initialized yet. + assert_eq!(reader.initialized(), 0); + + let buf = reader.fill_buf().unwrap(); + // We read one byte... + assert_eq!(buf.len(), 1); + // But we initialized the whole buffer! + assert_eq!(reader.initialized(), reader.capacity()); +} From f66eca1f135df9b050f474a962bf280725342b6f Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Thu, 13 Oct 2022 16:44:31 +0100 Subject: [PATCH 04/13] Ensure enum cast moves (cherry picked from commit de0396c7180f8e36165c3fefb9325b0ec1bfb5a2) --- compiler/rustc_mir_build/src/build/expr/as_rvalue.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 98bdaf0bc62e2..f88ab63f0b9d9 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -197,13 +197,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // create all the steps directly in MIR with operations all backends need to support anyway. let (source, ty) = if let ty::Adt(adt_def, ..) = source.ty.kind() && adt_def.is_enum() { let discr_ty = adt_def.repr().discr_type().to_ty(this.tcx); - let place = unpack!(block = this.as_place(block, source)); + let temp = unpack!(block = this.as_temp(block, scope, source, Mutability::Not)); let discr = this.temp(discr_ty, source.span); this.cfg.push_assign( block, source_info, discr, - Rvalue::Discriminant(place), + Rvalue::Discriminant(temp.into()), ); (Operand::Move(discr), discr_ty) From 8c36d46f5e23a30d756451f3b4801e1c0fd415ba Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Thu, 13 Oct 2022 17:24:19 +0100 Subject: [PATCH 05/13] Add test for issue 102389 (cherry picked from commit f1452fc1c99bc6d126a096694b0f70d9fe4734b6) --- src/test/ui/mir/issue-102389.rs | 8 ++++++++ src/test/ui/mir/issue-102389.stderr | 9 +++++++++ 2 files changed, 17 insertions(+) create mode 100644 src/test/ui/mir/issue-102389.rs create mode 100644 src/test/ui/mir/issue-102389.stderr diff --git a/src/test/ui/mir/issue-102389.rs b/src/test/ui/mir/issue-102389.rs new file mode 100644 index 0000000000000..8b27d5e55743d --- /dev/null +++ b/src/test/ui/mir/issue-102389.rs @@ -0,0 +1,8 @@ +enum Enum { A, B, C } + +fn func(inbounds: &Enum, array: &[i16; 3]) -> i16 { + array[*inbounds as usize] + //~^ ERROR [E0507] +} + +fn main() {} diff --git a/src/test/ui/mir/issue-102389.stderr b/src/test/ui/mir/issue-102389.stderr new file mode 100644 index 0000000000000..925dc258a4c3c --- /dev/null +++ b/src/test/ui/mir/issue-102389.stderr @@ -0,0 +1,9 @@ +error[E0507]: cannot move out of `*inbounds` which is behind a shared reference + --> $DIR/issue-102389.rs:4:11 + | +LL | array[*inbounds as usize] + | ^^^^^^^^^ move occurs because `*inbounds` has type `Enum`, which does not implement the `Copy` trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0507`. From b4ad734ee2cfac19d308217b7cef6135a4eccc1e Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Thu, 13 Oct 2022 17:24:27 +0100 Subject: [PATCH 06/13] Bless tests (cherry picked from commit 247da7b18de01886fb73a49f8b9ca59cfec16e64) --- src/test/mir-opt/enum_cast.bar.mir_map.0.mir | 10 +++-- src/test/mir-opt/enum_cast.boo.mir_map.0.mir | 10 +++-- .../mir-opt/enum_cast.droppy.mir_map.0.mir | 40 ++++++++++++------- src/test/mir-opt/enum_cast.foo.mir_map.0.mir | 10 +++-- 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/src/test/mir-opt/enum_cast.bar.mir_map.0.mir b/src/test/mir-opt/enum_cast.bar.mir_map.0.mir index afca2fd296075..59ec80915b4f2 100644 --- a/src/test/mir-opt/enum_cast.bar.mir_map.0.mir +++ b/src/test/mir-opt/enum_cast.bar.mir_map.0.mir @@ -3,11 +3,15 @@ fn bar(_1: Bar) -> usize { debug bar => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11 let mut _0: usize; // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26 - let mut _2: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + let _2: Bar; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + let mut _3: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 bb0: { - _2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 - _0 = move _2 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _2 = move _1; // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _3 = discriminant(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + _0 = move _3 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17 return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/enum_cast.boo.mir_map.0.mir b/src/test/mir-opt/enum_cast.boo.mir_map.0.mir index c79596d789953..f6903c1ec7971 100644 --- a/src/test/mir-opt/enum_cast.boo.mir_map.0.mir +++ b/src/test/mir-opt/enum_cast.boo.mir_map.0.mir @@ -3,11 +3,15 @@ fn boo(_1: Boo) -> usize { debug boo => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11 let mut _0: usize; // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26 - let mut _2: u8; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + let _2: Boo; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + let mut _3: u8; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 bb0: { - _2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 - _0 = move _2 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _2 = move _1; // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _3 = discriminant(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + _0 = move _3 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17 return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir b/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir index 8ced136db842a..98e1f8e118ed9 100644 --- a/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir +++ b/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir @@ -4,8 +4,9 @@ fn droppy() -> () { let mut _0: (); // return place in scope 0 at $DIR/enum_cast.rs:+0:13: +0:13 let _1: (); // in scope 0 at $DIR/enum_cast.rs:+1:5: +6:6 let _2: Droppy; // in scope 0 at $DIR/enum_cast.rs:+2:13: +2:14 - let mut _4: isize; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18 - let _5: Droppy; // in scope 0 at $DIR/enum_cast.rs:+7:9: +7:10 + let _4: Droppy; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18 + let mut _5: isize; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18 + let _6: Droppy; // in scope 0 at $DIR/enum_cast.rs:+7:9: +7:10 scope 1 { debug x => _2; // in scope 1 at $DIR/enum_cast.rs:+2:13: +2:14 scope 2 { @@ -16,7 +17,7 @@ fn droppy() -> () { } } scope 4 { - debug z => _5; // in scope 4 at $DIR/enum_cast.rs:+7:9: +7:10 + debug z => _6; // in scope 4 at $DIR/enum_cast.rs:+7:9: +7:10 } bb0: { @@ -25,30 +26,41 @@ fn droppy() -> () { _2 = Droppy::C; // scope 0 at $DIR/enum_cast.rs:+2:17: +2:26 FakeRead(ForLet(None), _2); // scope 0 at $DIR/enum_cast.rs:+2:13: +2:14 StorageLive(_3); // scope 3 at $DIR/enum_cast.rs:+5:13: +5:14 - _4 = discriminant(_2); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27 - _3 = move _4 as usize (Misc); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27 + StorageLive(_4); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18 + _4 = move _2; // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18 + _5 = discriminant(_4); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27 + _3 = move _5 as usize (Misc); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27 + drop(_4) -> [return: bb1, unwind: bb4]; // scope 3 at $DIR/enum_cast.rs:+5:26: +5:27 + } + + bb1: { + StorageDead(_4); // scope 3 at $DIR/enum_cast.rs:+5:26: +5:27 FakeRead(ForLet(None), _3); // scope 3 at $DIR/enum_cast.rs:+5:13: +5:14 _1 = const (); // scope 0 at $DIR/enum_cast.rs:+1:5: +6:6 StorageDead(_3); // scope 1 at $DIR/enum_cast.rs:+6:5: +6:6 - drop(_2) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6 + drop(_2) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6 } - bb1: { + bb2: { StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6 StorageDead(_1); // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6 - StorageLive(_5); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10 - _5 = Droppy::B; // scope 0 at $DIR/enum_cast.rs:+7:13: +7:22 - FakeRead(ForLet(None), _5); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10 + StorageLive(_6); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10 + _6 = Droppy::B; // scope 0 at $DIR/enum_cast.rs:+7:13: +7:22 + FakeRead(ForLet(None), _6); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10 _0 = const (); // scope 0 at $DIR/enum_cast.rs:+0:13: +8:2 - drop(_5) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2 + drop(_6) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2 } - bb2: { - StorageDead(_5); // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2 + bb3: { + StorageDead(_6); // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2 return; // scope 0 at $DIR/enum_cast.rs:+8:2: +8:2 } - bb3 (cleanup): { + bb4 (cleanup): { + drop(_2) -> bb5; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6 + } + + bb5 (cleanup): { resume; // scope 0 at $DIR/enum_cast.rs:+0:1: +8:2 } } diff --git a/src/test/mir-opt/enum_cast.foo.mir_map.0.mir b/src/test/mir-opt/enum_cast.foo.mir_map.0.mir index 39d6adeba33e9..aaa2d264667c4 100644 --- a/src/test/mir-opt/enum_cast.foo.mir_map.0.mir +++ b/src/test/mir-opt/enum_cast.foo.mir_map.0.mir @@ -3,11 +3,15 @@ fn foo(_1: Foo) -> usize { debug foo => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11 let mut _0: usize; // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26 - let mut _2: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + let _2: Foo; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + let mut _3: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 bb0: { - _2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 - _0 = move _2 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _2 = move _1; // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _3 = discriminant(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + _0 = move _3 as usize (Misc); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17 return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2 } } From 7539bc352bf67d0323d59d85f30a7598fe970296 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Thu, 13 Oct 2022 17:46:33 +0100 Subject: [PATCH 07/13] Fix test (cherry picked from commit 4a25a49edfcca0392a9731df351f1a1229a6e662) --- src/test/run-pass-valgrind/cast-enum-with-dtor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-pass-valgrind/cast-enum-with-dtor.rs b/src/test/run-pass-valgrind/cast-enum-with-dtor.rs index f29bc50e84c4e..f7ef92df8fbec 100644 --- a/src/test/run-pass-valgrind/cast-enum-with-dtor.rs +++ b/src/test/run-pass-valgrind/cast-enum-with-dtor.rs @@ -28,7 +28,7 @@ fn main() { { let e = E::C; assert_eq!(e as u32, 2); - assert_eq!(FLAG.load(Ordering::SeqCst), 0); + assert_eq!(FLAG.load(Ordering::SeqCst), 1); } assert_eq!(FLAG.load(Ordering::SeqCst), 1); } From 8f1050e0053abaf9c844cdb872eed73711b4c964 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Oct 2022 14:31:33 +1100 Subject: [PATCH 08/13] Tweak `deriving-all-codegen.rs`. To include some `Option<>` fields of different types in a single enum. The test output is currently buggy, but the next commit will fix that. (cherry picked from commit dfa9d5c971d74aa5bdf6b99253fe4b7db39f9b67) --- src/test/ui/deriving/deriving-all-codegen.rs | 2 +- src/test/ui/deriving/deriving-all-codegen.stdout | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/test/ui/deriving/deriving-all-codegen.rs b/src/test/ui/deriving/deriving-all-codegen.rs index aef79ae8a5b8d..ba7809413bd80 100644 --- a/src/test/ui/deriving/deriving-all-codegen.rs +++ b/src/test/ui/deriving/deriving-all-codegen.rs @@ -85,7 +85,7 @@ enum Mixed { P, Q, R(u32), - S { d1: u32, d2: u32 }, + S { d1: Option, d2: Option }, } // An enum with no fieldless variants. Note that `Default` cannot be derived diff --git a/src/test/ui/deriving/deriving-all-codegen.stdout b/src/test/ui/deriving/deriving-all-codegen.stdout index 65f7dec840802..6baa7317b12bb 100644 --- a/src/test/ui/deriving/deriving-all-codegen.stdout +++ b/src/test/ui/deriving/deriving-all-codegen.stdout @@ -789,8 +789,8 @@ enum Mixed { Q, R(u32), S { - d1: u32, - d2: u32, + d1: Option, + d2: Option, }, } #[automatically_derived] @@ -798,6 +798,7 @@ impl ::core::clone::Clone for Mixed { #[inline] fn clone(&self) -> Mixed { let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone>; *self } } @@ -864,6 +865,7 @@ impl ::core::cmp::Eq for Mixed { #[no_coverage] fn assert_receiver_is_total_eq(&self) -> () { let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; } } #[automatically_derived] From 692bc5b3ca777363759b760f7c67084a719dc2b6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Oct 2022 13:07:20 +1100 Subject: [PATCH 09/13] Fix `TyKind::is_simple_path`. PR #98758 introduced code to avoid redundant assertions in derived code like this: ``` let _: ::core::clone::AssertParamIsClone; let _: ::core::clone::AssertParamIsClone; ``` But the predicate `is_simple_path` introduced as part of this failed to account for generic arguments. Therefore the deriving code erroneously considers types like `Option` and `Option` to be the same. This commit fixes `is_simple_path`. Fixes #103157. (cherry picked from commit 9a23f60f9c801dd0b4686cc75c6a9979bd8928fa) --- compiler/rustc_ast/src/ast.rs | 7 +++-- .../ui/deriving/deriving-all-codegen.stdout | 2 ++ src/test/ui/deriving/issue-103157.rs | 12 ++++++++ src/test/ui/deriving/issue-103157.stderr | 30 +++++++++++++++++++ 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/deriving/issue-103157.rs create mode 100644 src/test/ui/deriving/issue-103157.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 6c514c75a500c..df94b70d27894 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2060,8 +2060,11 @@ impl TyKind { } pub fn is_simple_path(&self) -> Option { - if let TyKind::Path(None, Path { segments, .. }) = &self && segments.len() == 1 { - Some(segments[0].ident.name) + if let TyKind::Path(None, Path { segments, .. }) = &self + && let [segment] = &segments[..] + && segment.args.is_none() + { + Some(segment.ident.name) } else { None } diff --git a/src/test/ui/deriving/deriving-all-codegen.stdout b/src/test/ui/deriving/deriving-all-codegen.stdout index 6baa7317b12bb..56efc2a59ecb8 100644 --- a/src/test/ui/deriving/deriving-all-codegen.stdout +++ b/src/test/ui/deriving/deriving-all-codegen.stdout @@ -799,6 +799,7 @@ impl ::core::clone::Clone for Mixed { fn clone(&self) -> Mixed { let _: ::core::clone::AssertParamIsClone; let _: ::core::clone::AssertParamIsClone>; + let _: ::core::clone::AssertParamIsClone>; *self } } @@ -866,6 +867,7 @@ impl ::core::cmp::Eq for Mixed { fn assert_receiver_is_total_eq(&self) -> () { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; } } #[automatically_derived] diff --git a/src/test/ui/deriving/issue-103157.rs b/src/test/ui/deriving/issue-103157.rs new file mode 100644 index 0000000000000..52b4c7898d87b --- /dev/null +++ b/src/test/ui/deriving/issue-103157.rs @@ -0,0 +1,12 @@ +// check-fail + +#[derive(PartialEq, Eq)] +pub enum Value { + Boolean(Option), + Float(Option), //~ ERROR the trait bound `f64: Eq` is not satisfied +} + +fn main() { + let a = Value::Float(Some(f64::NAN)); + assert!(a == a); +} diff --git a/src/test/ui/deriving/issue-103157.stderr b/src/test/ui/deriving/issue-103157.stderr new file mode 100644 index 0000000000000..ee3528fe1062d --- /dev/null +++ b/src/test/ui/deriving/issue-103157.stderr @@ -0,0 +1,30 @@ +error[E0277]: the trait bound `f64: Eq` is not satisfied + --> $DIR/issue-103157.rs:6:11 + | +LL | #[derive(PartialEq, Eq)] + | -- in this derive macro expansion +... +LL | Float(Option), + | ^^^^^^^^^^^ the trait `Eq` is not implemented for `f64` + | + = help: the following other types implement trait `Eq`: + i128 + i16 + i32 + i64 + i8 + isize + u128 + u16 + and 4 others + = note: required for `Option` to implement `Eq` +note: required by a bound in `AssertParamIsEq` + --> $SRC_DIR/core/src/cmp.rs:LL:COL + | +LL | pub struct AssertParamIsEq { + | ^^ required by this bound in `AssertParamIsEq` + = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From 2396c204887a2b712721cd074eefa598a2a760ad Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 19 Oct 2022 16:49:21 -0300 Subject: [PATCH 10/13] Extract orig_opt_local_def_id as a function (cherry picked from commit fb5475887f8f3641aea994e1f8f8954d1290449a) --- compiler/rustc_ast_lowering/src/lib.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index d2ce6bdb08e58..9ba167599825a 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -499,6 +499,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { start } + /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name + /// resolver (if any). + fn orig_opt_local_def_id(&self, node: NodeId) -> Option { + self.resolver.node_id_to_def_id.get(&node).map(|local_def_id| *local_def_id) + } + + fn orig_local_def_id(&self, node: NodeId) -> LocalDefId { + self.orig_opt_local_def_id(node) + .unwrap_or_else(|| panic!("no entry for node id: `{:?}`", node)) + } + /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name /// resolver (if any), after applying any remapping from `get_remapped_def_id`. /// @@ -513,10 +524,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// we would create an opaque type `type FooReturn<'a1> = impl Debug + 'a1`. /// When lowering the `Debug + 'a` bounds, we add a remapping to map `'a` to `'a1`. fn opt_local_def_id(&self, node: NodeId) -> Option { - self.resolver - .node_id_to_def_id - .get(&node) - .map(|local_def_id| self.get_remapped_def_id(*local_def_id)) + self.orig_opt_local_def_id(node).map(|local_def_id| self.get_remapped_def_id(local_def_id)) } fn local_def_id(&self, node: NodeId) -> LocalDefId { From 5dbca914b59a14f0fa07ad1e18f4e2f658177212 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 18 Oct 2022 14:05:17 -0300 Subject: [PATCH 11/13] Do anonymous lifetimes remapping correctly for nested rpits (cherry picked from commit 49ce8a22b05d779da4ffc531a44380656d51404b) --- compiler/rustc_ast_lowering/src/lib.rs | 27 ++++++++----------- .../nested-rpit-with-anonymous-lifetimes.rs | 23 ++++++++++++++++ 2 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 src/test/ui/impl-trait/nested-rpit-with-anonymous-lifetimes.rs diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 9ba167599825a..9012aa7049035 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -533,9 +533,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// Get the previously recorded `to` local def id given the `from` local def id, obtained using /// `generics_def_id_map` field. - fn get_remapped_def_id(&self, mut local_def_id: LocalDefId) -> LocalDefId { + fn get_remapped_def_id(&self, local_def_id: LocalDefId) -> LocalDefId { // `generics_def_id_map` is a stack of mappings. As we go deeper in impl traits nesting we - // push new mappings so we need to try first the latest mappings, hence `iter().rev()`. + // push new mappings, so we first need to get the latest (innermost) mappings, hence `iter().rev()`. // // Consider: // @@ -545,18 +545,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // // `[[fn#'b -> impl_trait#'b], [fn#'b -> impl_sized#'b]]` // - // for the opaque type generated on `impl Sized + 'b`, We want the result to be: - // impl_sized#'b, so iterating forward is the wrong thing to do. - for map in self.generics_def_id_map.iter().rev() { - if let Some(r) = map.get(&local_def_id) { - debug!("def_id_remapper: remapping from `{local_def_id:?}` to `{r:?}`"); - local_def_id = *r; - } else { - debug!("def_id_remapper: no remapping for `{local_def_id:?}` found in map"); - } - } - - local_def_id + // for the opaque type generated on `impl Sized + 'b`, we want the result to be: impl_sized#'b. + // So, if we were trying to find first from the start (outermost) would give the wrong result, impl_trait#'b. + self.generics_def_id_map + .iter() + .rev() + .find_map(|map| map.get(&local_def_id).map(|local_def_id| *local_def_id)) + .unwrap_or(local_def_id) } /// Freshen the `LoweringContext` and ready it to lower a nested item. @@ -1615,7 +1610,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { LifetimeRes::Fresh { param, binder: _ } => { debug_assert_eq!(lifetime.ident.name, kw::UnderscoreLifetime); - if let Some(old_def_id) = self.opt_local_def_id(param) && remapping.get(&old_def_id).is_none() { + if let Some(old_def_id) = self.orig_opt_local_def_id(param) && remapping.get(&old_def_id).is_none() { let node_id = self.next_node_id(); let new_def_id = self.create_def( @@ -1884,7 +1879,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let extra_lifetime_params = self.resolver.take_extra_lifetime_params(opaque_ty_node_id); debug!(?extra_lifetime_params); for (ident, outer_node_id, outer_res) in extra_lifetime_params { - let outer_def_id = self.local_def_id(outer_node_id); + let outer_def_id = self.orig_local_def_id(outer_node_id); let inner_node_id = self.next_node_id(); // Add a definition for the in scope lifetime def. diff --git a/src/test/ui/impl-trait/nested-rpit-with-anonymous-lifetimes.rs b/src/test/ui/impl-trait/nested-rpit-with-anonymous-lifetimes.rs new file mode 100644 index 0000000000000..287a030cf876b --- /dev/null +++ b/src/test/ui/impl-trait/nested-rpit-with-anonymous-lifetimes.rs @@ -0,0 +1,23 @@ +// check-pass + +pub struct VecNumber<'s> { + pub vec_number: Vec>, + pub auxiliary_object: &'s Vec, +} + +pub struct Number<'s> { + pub number: &'s usize, +} + +impl<'s> VecNumber<'s> { + pub fn vec_number_iterable_per_item_in_auxiliary_object( + &self, + ) -> impl Iterator>)> { + self.auxiliary_object.iter().map(move |n| { + let iter_number = self.vec_number.iter(); + (n, iter_number) + }) + } +} + +fn main() {} From b1fb60e5a654f2cd1799212a6d0e043777886012 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Thu, 20 Oct 2022 21:22:32 +0800 Subject: [PATCH 12/13] [beta] Update cargo 1 commits in 082503982ea0fb7a8fd72210427d43a2e2128a63..4bc8f24d3e899462e43621aab981f6383a370365 2022-09-13 17:49:38 +0000 to 2022-10-20 06:00:42 +0000 - [BETA-1.65] Fix deadlock when build scripts are waiting for input on stdin (rust-lang/cargo#11257) --- Cargo.lock | 2 +- src/tools/cargo | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 69f96bcbe63b4..fda523611a50a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -435,7 +435,7 @@ dependencies = [ [[package]] name = "cargo-util" -version = "0.2.1" +version = "0.2.2" dependencies = [ "anyhow", "core-foundation", diff --git a/src/tools/cargo b/src/tools/cargo index 082503982ea0f..4bc8f24d3e899 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 082503982ea0fb7a8fd72210427d43a2e2128a63 +Subproject commit 4bc8f24d3e899462e43621aab981f6383a370365 From 731bbc854db4bd6dbf5a2e277e4ea1230d1e4c68 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 15 Oct 2022 22:01:28 +0400 Subject: [PATCH 13/13] linker: Fix weak lang item linking with combination windows-gnu + LLD + LTO (cherry picked from commit acf51e13457c45b97cdfd551d85d3e75140e0ff7) --- compiler/rustc_codegen_ssa/src/back/link.rs | 2 +- compiler/rustc_codegen_ssa/src/base.rs | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index c5e18c7fae896..ea0f0de76c58f 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2698,7 +2698,7 @@ fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool { } } -fn are_upstream_rust_objects_already_included(sess: &Session) -> bool { +pub(crate) fn are_upstream_rust_objects_already_included(sess: &Session) -> bool { match sess.lto() { config::Lto::Fat => true, config::Lto::Thin => { diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 35fd86c173578..b98ff495778a6 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -1,3 +1,4 @@ +use crate::back::link::are_upstream_rust_objects_already_included; use crate::back::metadata::create_compressed_metadata_file; use crate::back::write::{ compute_per_cgu_lto_type, start_async_codegen, submit_codegened_module_to_llvm, @@ -854,10 +855,14 @@ impl CrateInfo { // Handle circular dependencies in the standard library. // See comment before `add_linked_symbol_object` function for the details. - // With msvc-like linkers it's both unnecessary (they support circular dependencies), - // and causes linking issues (when weak lang item symbols are "privatized" by LTO). + // If global LTO is enabled then almost everything (*) is glued into a single object file, + // so this logic is not necessary and can cause issues on some targets (due to weak lang + // item symbols being "privatized" to that object file), so we disable it. + // (*) Native libs, and `#[compiler_builtins]` and `#[no_builtins]` crates are not glued, + // and we assume that they cannot define weak lang items. This is not currently enforced + // by the compiler, but that's ok because all this stuff is unstable anyway. let target = &tcx.sess.target; - if !target.is_like_msvc { + if !are_upstream_rust_objects_already_included(tcx.sess) { let missing_weak_lang_items: FxHashSet<&Symbol> = info .used_crates .iter()