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/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/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index d2ce6bdb08e58..9012aa7049035 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 { @@ -525,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: // @@ -537,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. @@ -1607,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( @@ -1876,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/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() 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/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) 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()); +} 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/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 } } 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); } 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"]' \ 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..56efc2a59ecb8 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,8 @@ impl ::core::clone::Clone for Mixed { #[inline] fn clone(&self) -> Mixed { let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone>; + let _: ::core::clone::AssertParamIsClone>; *self } } @@ -864,6 +866,8 @@ impl ::core::cmp::Eq for Mixed { #[no_coverage] 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`. 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() {} 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`. 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`. 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