From 2c9d857e904e36acb3ea28ea24ed25c1b96ffa5d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 Apr 2020 12:03:06 +0200 Subject: [PATCH 01/20] Miri leak_report: do not report leaks of allocations that are reachable from globals --- src/librustc_mir/interpret/memory.rs | 29 +++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 04a927c69a6..a97df313ea0 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -650,7 +650,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { allocs_to_print: &mut VecDeque, alloc: &Allocation, ) { - for &(_, (_, target_id)) in alloc.relocations().iter() { + for &(_, target_id) in alloc.relocations().values() { if allocs_seen.insert(target_id) { allocs_to_print.push_back(target_id); } @@ -713,12 +713,31 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } pub fn leak_report(&self) -> usize { - let leaks: Vec<_> = self - .alloc_map - .filter_map_collect(|&id, &(kind, _)| if kind.may_leak() { None } else { Some(id) }); + // Collect the set of allocations that are *reachable* from `Global` allocations. + let reachable = { + let mut reachable = FxHashSet::default(); + let global_kind = M::GLOBAL_KIND.map(MemoryKind::Machine); + let mut todo: Vec<_> = self.alloc_map.filter_map_collect(move |&id, &(kind, _)| { + if Some(kind) == global_kind { Some(id) } else { None } + }); + while let Some(id) = todo.pop() { + if reachable.insert(id) { + if let Some((_, alloc)) = self.alloc_map.get(id) { + // This is a new allocation, add its relocations to `todo`. + todo.extend(alloc.relocations().values().map(|&(_, target_id)| target_id)); + } + } + } + reachable + }; + + // All allocations that are *not* `reachable` and *not* `may_leak` are considered leaking. + let leaks: Vec<_> = self.alloc_map.filter_map_collect(|&id, &(kind, _)| { + if kind.may_leak() || reachable.contains(&id) { None } else { Some(id) } + }); let n = leaks.len(); if n > 0 { - eprintln!("### LEAK REPORT ###"); + eprintln!("The following memory was leaked:"); self.dump_allocs(leaks); } n From fbdff5145ac3f6ecfe7bde656cfa41f5a77c8f10 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 Apr 2020 12:19:10 +0200 Subject: [PATCH 02/20] avoid printing allocations twice --- src/librustc_mir/interpret/machine.rs | 2 +- src/librustc_mir/interpret/memory.rs | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index 48082a1e346..8875baad58c 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -51,7 +51,7 @@ pub trait AllocMap { where K: Borrow; - /// Returns data based the keys and values in the map. + /// Returns data based on the keys and values in the map. fn filter_map_collect(&self, f: impl FnMut(&K, &V) -> Option) -> Vec; /// Returns a reference to entry `k`. If no such entry exists, call diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index a97df313ea0..66357a48634 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -646,14 +646,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { fn dump_alloc_helper( &self, - allocs_seen: &mut FxHashSet, allocs_to_print: &mut VecDeque, alloc: &Allocation, ) { for &(_, target_id) in alloc.relocations().values() { - if allocs_seen.insert(target_id) { - allocs_to_print.push_back(target_id); - } + allocs_to_print.push_back(target_id); } crate::util::pretty::write_allocation(self.tcx.tcx, alloc, &mut std::io::stderr(), "") .unwrap(); @@ -666,9 +663,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { allocs.sort(); allocs.dedup(); let mut allocs_to_print = VecDeque::from(allocs); - let mut allocs_seen = FxHashSet::default(); + // `allocs_printed` contains all allocations that we have already printed. + let mut allocs_printed = FxHashSet::default(); while let Some(id) = allocs_to_print.pop_front() { + if !allocs_printed.insert(id) { + // Already printed, so skip this. + continue; + } eprint!("Alloc {:<5}: ", id); fn msg(alloc: &Allocation, extra: &str) { eprintln!( @@ -688,14 +690,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { MemoryKind::CallerLocation => msg(alloc, " (caller_location)"), MemoryKind::Machine(m) => msg(alloc, &format!(" ({:?})", m)), }; - self.dump_alloc_helper(&mut allocs_seen, &mut allocs_to_print, alloc); + self.dump_alloc_helper(&mut allocs_to_print, alloc); } Err(()) => { // global alloc? match self.tcx.alloc_map.lock().get(id) { Some(GlobalAlloc::Memory(alloc)) => { msg(alloc, " (immutable)"); - self.dump_alloc_helper(&mut allocs_seen, &mut allocs_to_print, alloc); + self.dump_alloc_helper(&mut allocs_to_print, alloc); } Some(GlobalAlloc::Function(func)) => { eprintln!("{}", func); @@ -722,8 +724,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { }); while let Some(id) = todo.pop() { if reachable.insert(id) { + // This is a new allocation, add its relocations to `todo`. if let Some((_, alloc)) = self.alloc_map.get(id) { - // This is a new allocation, add its relocations to `todo`. todo.extend(alloc.relocations().values().map(|&(_, target_id)| target_id)); } } From aecaeab5ec47ca34da95b4730cbfe80a19ce6fe6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 Apr 2020 13:21:25 +0200 Subject: [PATCH 03/20] share more alloc printing code between Miri and MIR dumping --- src/librustc_mir/interpret/memory.rs | 71 +++++++++++++--------------- src/librustc_mir/util/pretty.rs | 70 +++++++++++++++++---------- 2 files changed, 78 insertions(+), 63 deletions(-) diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 66357a48634..e61b0796cc1 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -20,6 +20,7 @@ use super::{ AllocId, AllocMap, Allocation, AllocationExtra, CheckInAllocMsg, ErrorHandled, GlobalAlloc, GlobalId, InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Scalar, }; +use crate::util::pretty; #[derive(Debug, PartialEq, Copy, Clone)] pub enum MemoryKind { @@ -644,22 +645,22 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { self.dump_allocs(vec![id]); } - fn dump_alloc_helper( - &self, - allocs_to_print: &mut VecDeque, - alloc: &Allocation, - ) { - for &(_, target_id) in alloc.relocations().values() { - allocs_to_print.push_back(target_id); - } - crate::util::pretty::write_allocation(self.tcx.tcx, alloc, &mut std::io::stderr(), "") - .unwrap(); - } - /// Print a list of allocations and all allocations they point to, recursively. /// This prints directly to stderr, ignoring RUSTC_LOG! It is up to the caller to /// control for this. pub fn dump_allocs(&self, mut allocs: Vec) { + // Cannot be a closure because it is generic in `Tag`, `Extra`. + fn write_allocation_track_relocs<'tcx, Tag, Extra>( + tcx: TyCtxtAt<'tcx>, + allocs_to_print: &mut VecDeque, + alloc: &Allocation, + ) { + for &(_, target_id) in alloc.relocations().values() { + allocs_to_print.push_back(target_id); + } + pretty::write_allocation(tcx.tcx, alloc, &mut std::io::stderr()).unwrap(); + } + allocs.sort(); allocs.dedup(); let mut allocs_to_print = VecDeque::from(allocs); @@ -671,46 +672,42 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // Already printed, so skip this. continue; } - eprint!("Alloc {:<5}: ", id); - fn msg(alloc: &Allocation, extra: &str) { - eprintln!( - "({} bytes, alignment {}){}", - alloc.size.bytes(), - alloc.align.bytes(), - extra - ) - }; - // normal alloc? - match self.alloc_map.get_or(id, || Err(())) { - Ok((kind, alloc)) => { + eprint!("{}", id); + match self.alloc_map.get(id) { + Some(&(kind, ref alloc)) => { + // normal alloc match kind { - MemoryKind::Stack => msg(alloc, " (stack)"), - MemoryKind::Vtable => msg(alloc, " (vtable)"), - MemoryKind::CallerLocation => msg(alloc, " (caller_location)"), - MemoryKind::Machine(m) => msg(alloc, &format!(" ({:?})", m)), + MemoryKind::Stack => eprint!(" (stack variable, "), + MemoryKind::Vtable => eprint!(" (vtable, "), + MemoryKind::CallerLocation => eprint!(" (caller_location, "), + MemoryKind::Machine(m) if Some(m) == M::GLOBAL_KIND => { + eprint!(" (global, ") + } + MemoryKind::Machine(m) => eprint!(" ({:?}, ", m), }; - self.dump_alloc_helper(&mut allocs_to_print, alloc); + write_allocation_track_relocs(self.tcx, &mut allocs_to_print, alloc); } - Err(()) => { - // global alloc? + None => { + // global alloc match self.tcx.alloc_map.lock().get(id) { Some(GlobalAlloc::Memory(alloc)) => { - msg(alloc, " (immutable)"); - self.dump_alloc_helper(&mut allocs_to_print, alloc); + eprint!(" (global, "); + write_allocation_track_relocs(self.tcx, &mut allocs_to_print, alloc); } Some(GlobalAlloc::Function(func)) => { - eprintln!("{}", func); + eprint!(" (fn: {})", func); } Some(GlobalAlloc::Static(did)) => { - eprintln!("{:?}", did); + eprint!(" (static: {})", self.tcx.def_path_str(did)); } None => { - eprintln!("(deallocated)"); + eprint!(" (deallocated)"); } } } - }; + } + eprintln!(); } } diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index a81fcb54580..64221c41bff 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -567,26 +567,21 @@ pub fn write_allocations<'tcx>( } let mut visitor = CollectAllocIds(Default::default()); body.visit_with(&mut visitor); + // `seen` contains all seen allocations, including the ones we have *not* printed yet. + // The protocol is to first `insert` into `seen`, and only if that returns `true` + // then push to `todo`. let mut seen = visitor.0; let mut todo: Vec<_> = seen.iter().copied().collect(); while let Some(id) = todo.pop() { - let mut write_header_and_allocation = + let mut write_allocation_track_relocs = |w: &mut dyn Write, alloc: &Allocation| -> io::Result<()> { - write!(w, "size: {}, align: {})", alloc.size.bytes(), alloc.align.bytes())?; - if alloc.size == Size::ZERO { - write!(w, " {{}}")?; - } else { - writeln!(w, " {{")?; - write_allocation(tcx, alloc, w, " ")?; - write!(w, "}}")?; - // `.rev()` because we are popping them from the back of the `todo` vector. - for id in alloc_ids_from_alloc(alloc).rev() { - if seen.insert(id) { - todo.push(id); - } + // `.rev()` because we are popping them from the back of the `todo` vector. + for id in alloc_ids_from_alloc(alloc).rev() { + if seen.insert(id) { + todo.push(id); } } - Ok(()) + write_allocation(tcx, alloc, w) }; write!(w, "\n{}", id)?; let alloc = tcx.alloc_map.lock().get(id); @@ -599,7 +594,7 @@ pub fn write_allocations<'tcx>( match tcx.const_eval_poly(did) { Ok(ConstValue::ByRef { alloc, .. }) => { write!(w, " (static: {}, ", tcx.def_path_str(did))?; - write_header_and_allocation(w, alloc)?; + write_allocation_track_relocs(w, alloc)?; } Ok(_) => { span_bug!(tcx.def_span(did), " static item without `ByRef` initializer") @@ -616,15 +611,46 @@ pub fn write_allocations<'tcx>( } Some(GlobalAlloc::Memory(alloc)) => { write!(w, " (")?; - write_header_and_allocation(w, alloc)? + write_allocation_track_relocs(w, alloc)? } } - writeln!(w)?; } Ok(()) } +/// Dumps the size and metadata and content of an allocation to the given writer. +/// The expectation is that the caller first prints other relevant metadata, so the exact +/// format of this function is (*without* leading or trailing newline): +/// ``` +/// size: {}, align: {}) { +/// +/// } +/// ``` +/// +/// The byte format is similar to how hex editors print bytes. Each line starts with the address of +/// the start of the line, followed by all bytes in hex format (space separated). +/// If the allocation is small enough to fit into a single line, no start address is given. +/// After the hex dump, an ascii dump follows, replacing all unprintable characters (control +/// characters or characters whose value is larger than 127) with a `.` +/// This also prints relocations adequately. +pub fn write_allocation( + tcx: TyCtxt<'tcx>, + alloc: &Allocation, + w: &mut dyn Write, +) -> io::Result<()> { + write!(w, "size: {}, align: {})", alloc.size.bytes(), alloc.align.bytes())?; + if alloc.size == Size::ZERO { + // We are done. + return write!(w, " {{}}"); + } + // Write allocation bytes. + writeln!(w, " {{")?; + write_allocation_bytes(tcx, alloc, w, " ")?; + write!(w, "}}")?; + Ok(()) +} + fn write_allocation_endline(w: &mut dyn Write, ascii: &str) -> io::Result<()> { for _ in 0..(BYTES_PER_LINE - ascii.chars().count()) { write!(w, " ")?; @@ -649,18 +675,10 @@ fn write_allocation_newline( Ok(line_start) } -/// Dumps the bytes of an allocation to the given writer. This also prints relocations instead of -/// the raw bytes where applicable. -/// The byte format is similar to how hex editors print bytes. Each line starts with the address of -/// the start of the line, followed by all bytes in hex format (space separated). -/// If the allocation is small enough to fit into a single line, no start address is given. -/// After the hex dump, an ascii dump follows, replacing all unprintable characters (control -/// characters or characters whose value is larger than 127) with a `.` -/// /// The `prefix` argument allows callers to add an arbitrary prefix before each line (even if there /// is only one line). Note that your prefix should contain a trailing space as the lines are /// printed directly after it. -pub fn write_allocation( +fn write_allocation_bytes( tcx: TyCtxt<'tcx>, alloc: &Allocation, w: &mut dyn Write, From 1f3e2478b2e7267034d30a76ef4d28791a57d925 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 Apr 2020 13:34:18 +0200 Subject: [PATCH 04/20] indicate better which kind of memory got leaked --- src/librustc_mir/interpret/machine.rs | 2 +- src/librustc_mir/interpret/memory.rs | 26 +++++++++++++++----------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index 8875baad58c..23e39f433f5 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -79,7 +79,7 @@ pub trait AllocMap { /// and some use case dependent behaviour can instead be applied. pub trait Machine<'mir, 'tcx>: Sized { /// Additional memory kinds a machine wishes to distinguish from the builtin ones - type MemoryKind: ::std::fmt::Debug + MayLeak + Eq + 'static; + type MemoryKind: ::std::fmt::Debug + ::std::fmt::Display + MayLeak + Eq + 'static; /// Tag tracked alongside every pointer. This is used to implement "Stacked Borrows" /// . diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index e61b0796cc1..c16c59715e4 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -9,6 +9,7 @@ use std::borrow::Cow; use std::collections::VecDeque; use std::convert::TryFrom; +use std::fmt; use std::ptr; use rustc_ast::ast::Mutability; @@ -46,6 +47,17 @@ impl MayLeak for MemoryKind { } } +impl fmt::Display for MemoryKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + MemoryKind::Stack => write!(f, "stack variable"), + MemoryKind::Vtable => write!(f, "vtable"), + MemoryKind::CallerLocation => write!(f, "caller location"), + MemoryKind::Machine(m) => write!(f, "{}", m), + } + } +} + /// Used by `get_size_and_align` to indicate whether the allocation needs to be live. #[derive(Debug, Copy, Clone)] pub enum AllocCheck { @@ -259,7 +271,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { if alloc_kind != kind { throw_ub_format!( - "deallocating `{:?}` memory using `{:?}` deallocation operation", + "deallocating {} memory using {} deallocation operation", alloc_kind, kind ); @@ -677,22 +689,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { match self.alloc_map.get(id) { Some(&(kind, ref alloc)) => { // normal alloc - match kind { - MemoryKind::Stack => eprint!(" (stack variable, "), - MemoryKind::Vtable => eprint!(" (vtable, "), - MemoryKind::CallerLocation => eprint!(" (caller_location, "), - MemoryKind::Machine(m) if Some(m) == M::GLOBAL_KIND => { - eprint!(" (global, ") - } - MemoryKind::Machine(m) => eprint!(" ({:?}, ", m), - }; + eprint!(" ({}, ", kind); write_allocation_track_relocs(self.tcx, &mut allocs_to_print, alloc); } None => { // global alloc match self.tcx.alloc_map.lock().get(id) { Some(GlobalAlloc::Memory(alloc)) => { - eprint!(" (global, "); + eprint!(" (unchanged global, "); write_allocation_track_relocs(self.tcx, &mut allocs_to_print, alloc); } Some(GlobalAlloc::Function(func)) => { From c8b83babf358cd3094fb05a65889a6d017a81d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Mon, 6 Apr 2020 00:00:00 +0000 Subject: [PATCH 05/20] Keep codegen units unmerged when building compiler builtins --- src/librustc_mir/monomorphize/partitioning.rs | 9 ++++- .../partitioning/compiler-builtins.rs | 40 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 src/test/codegen-units/partitioning/compiler-builtins.rs diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 9068c0541a4..44aa9a710b6 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -455,11 +455,18 @@ fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibilit fn merge_codegen_units<'tcx>( tcx: TyCtxt<'tcx>, initial_partitioning: &mut PreInliningPartitioning<'tcx>, - target_cgu_count: usize, + mut target_cgu_count: usize, ) { assert!(target_cgu_count >= 1); let codegen_units = &mut initial_partitioning.codegen_units; + if tcx.is_compiler_builtins(LOCAL_CRATE) { + // Compiler builtins require some degree of control over how mono items + // are partitioned into compilation units. Provide it by keeping the + // original partitioning when compiling the compiler builtins crate. + target_cgu_count = codegen_units.len(); + } + // Note that at this point in time the `codegen_units` here may not be in a // deterministic order (but we know they're deterministically the same set). // We want this merging to produce a deterministic ordering of codegen units diff --git a/src/test/codegen-units/partitioning/compiler-builtins.rs b/src/test/codegen-units/partitioning/compiler-builtins.rs new file mode 100644 index 00000000000..25195743b04 --- /dev/null +++ b/src/test/codegen-units/partitioning/compiler-builtins.rs @@ -0,0 +1,40 @@ +// Verifies that during compiler_builtins compilation the codegen units are kept +// unmerged. Even when only a single codegen unit is requested with -Ccodegen-units=1. +// +// compile-flags: -Zprint-mono-items=eager -Ccodegen-units=1 + +#![compiler_builtins] +#![crate_type="lib"] +#![feature(compiler_builtins)] + +mod atomics { + //~ MONO_ITEM fn compiler_builtins::atomics[0]::sync_1[0] @@ compiler_builtins-cgu.0[External] + #[no_mangle] + pub extern "C" fn sync_1() {} + + //~ MONO_ITEM fn compiler_builtins::atomics[0]::sync_2[0] @@ compiler_builtins-cgu.0[External] + #[no_mangle] + pub extern "C" fn sync_2() {} + + //~ MONO_ITEM fn compiler_builtins::atomics[0]::sync_3[0] @@ compiler_builtins-cgu.0[External] + #[no_mangle] + pub extern "C" fn sync_3() {} +} + +mod x { + //~ MONO_ITEM fn compiler_builtins::x[0]::x[0] @@ compiler_builtins-cgu.1[External] + #[no_mangle] + pub extern "C" fn x() {} +} + +mod y { + //~ MONO_ITEM fn compiler_builtins::y[0]::y[0] @@ compiler_builtins-cgu.2[External] + #[no_mangle] + pub extern "C" fn y() {} +} + +mod z { + //~ MONO_ITEM fn compiler_builtins::z[0]::z[0] @@ compiler_builtins-cgu.3[External] + #[no_mangle] + pub extern "C" fn z() {} +} From e1a36e89db5436b4e91e2e2014e760f48bbf161d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Mon, 6 Apr 2020 22:13:31 +0200 Subject: [PATCH 06/20] Bump nomicon submodule --- src/doc/nomicon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/nomicon b/src/doc/nomicon index 411197b0e77..6eb24d6e9c0 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 411197b0e77590c967e37e8f6ec681abd359afe8 +Subproject commit 6eb24d6e9c0773d4aee68ed5fca121ce3cdf676a From d0a78ea94ae207ec965c35753c297e7ba6f77c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Mon, 6 Apr 2020 22:14:35 +0200 Subject: [PATCH 07/20] Bump rust-by-example submodule --- src/doc/rust-by-example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index edd2a7e6873..a6638463efc 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit edd2a7e687358712608896730c083cb76c7b401a +Subproject commit a6638463efc7631bc0e8dc67ccd256d4e1b61f1a From 01b3293e492a7bc99e92c52d2df70ad602a6dfc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Mon, 6 Apr 2020 22:16:09 +0200 Subject: [PATCH 08/20] Bump stdarch submodule --- src/stdarch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stdarch b/src/stdarch index abe96ca3b87..1a577bd78e8 160000 --- a/src/stdarch +++ b/src/stdarch @@ -1 +1 @@ -Subproject commit abe96ca3b87fcca6aa1dfcefd40d8c8d92d2e673 +Subproject commit 1a577bd78e84e357e29c5336ff8beb432873046b From 65e10e343608e2e42b93ec17eae01babfb1e3b8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Mon, 6 Apr 2020 22:44:04 +0200 Subject: [PATCH 09/20] Use assoc const f32::NAN in liballoc --- src/liballoc/tests/arc.rs | 2 +- src/liballoc/tests/rc.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/liballoc/tests/arc.rs b/src/liballoc/tests/arc.rs index 34384cfcba9..c02ba267056 100644 --- a/src/liballoc/tests/arc.rs +++ b/src/liballoc/tests/arc.rs @@ -50,7 +50,7 @@ fn trait_object() { #[test] fn float_nan_ne() { - let x = Arc::new(std::f32::NAN); + let x = Arc::new(f32::NAN); assert!(x != x); assert!(!(x == x)); } diff --git a/src/liballoc/tests/rc.rs b/src/liballoc/tests/rc.rs index 884856cd1b4..501b4f0f816 100644 --- a/src/liballoc/tests/rc.rs +++ b/src/liballoc/tests/rc.rs @@ -50,7 +50,7 @@ fn trait_object() { #[test] fn float_nan_ne() { - let x = Rc::new(std::f32::NAN); + let x = Rc::new(f32::NAN); assert!(x != x); assert!(!(x == x)); } From cf1c7edd2dfd54d2fb4969f1b910c644e8b74f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Mon, 6 Apr 2020 22:44:51 +0200 Subject: [PATCH 10/20] Use assoc float consts in libcore --- src/libcore/benches/num/dec2flt/mod.rs | 1 - src/libcore/benches/num/flt2dec/mod.rs | 1 - src/libcore/tests/iter.rs | 3 +-- src/libcore/tests/num/dec2flt/rawfp.rs | 2 -- src/libcore/tests/num/mod.rs | 6 ++---- src/libcore/tests/ops.rs | 18 ++++++++---------- src/libcore/tests/slice.rs | 2 +- src/libcore/tests/tuple.rs | 13 ++++++------- 8 files changed, 18 insertions(+), 28 deletions(-) diff --git a/src/libcore/benches/num/dec2flt/mod.rs b/src/libcore/benches/num/dec2flt/mod.rs index 561a4bee87a..305baa68729 100644 --- a/src/libcore/benches/num/dec2flt/mod.rs +++ b/src/libcore/benches/num/dec2flt/mod.rs @@ -1,4 +1,3 @@ -use std::f64; use test::Bencher; #[bench] diff --git a/src/libcore/benches/num/flt2dec/mod.rs b/src/libcore/benches/num/flt2dec/mod.rs index b810dd12ab6..a1ce33d0bb4 100644 --- a/src/libcore/benches/num/flt2dec/mod.rs +++ b/src/libcore/benches/num/flt2dec/mod.rs @@ -5,7 +5,6 @@ mod strategy { use core::num::flt2dec::MAX_SIG_DIGITS; use core::num::flt2dec::{decode, DecodableFloat, Decoded, FullDecoded}; -use std::f64; use std::io::Write; use std::vec::Vec; use test::Bencher; diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index e0954a661c8..1a1dbcd7b87 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -76,7 +76,6 @@ fn test_cmp_by() { #[test] fn test_partial_cmp_by() { use core::cmp::Ordering; - use core::f64; let f = |x: i32, y: i32| (x * x).partial_cmp(&y); let xs = || [1, 2, 3, 4].iter().copied(); @@ -2894,7 +2893,7 @@ fn test_is_sorted() { assert!(![1, 3, 2].iter().is_sorted()); assert!([0].iter().is_sorted()); assert!(std::iter::empty::().is_sorted()); - assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted()); + assert!(![0.0, 1.0, f32::NAN].iter().is_sorted()); assert!([-2, -1, 0, 3].iter().is_sorted()); assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); assert!(!["c", "bb", "aaa"].iter().is_sorted()); diff --git a/src/libcore/tests/num/dec2flt/rawfp.rs b/src/libcore/tests/num/dec2flt/rawfp.rs index 665fb6b9efb..c098b9c2ba2 100644 --- a/src/libcore/tests/num/dec2flt/rawfp.rs +++ b/src/libcore/tests/num/dec2flt/rawfp.rs @@ -1,8 +1,6 @@ use core::num::dec2flt::rawfp::RawFloat; use core::num::dec2flt::rawfp::{fp_to_float, next_float, prev_float, round_normal}; use core::num::diy_float::Fp; -use std::f32; -use std::f64; fn integer_decode(f: f64) -> (u64, i16, i8) { RawFloat::integer_decode(f) diff --git a/src/libcore/tests/num/mod.rs b/src/libcore/tests/num/mod.rs index f61793a3bca..181bbb8e187 100644 --- a/src/libcore/tests/num/mod.rs +++ b/src/libcore/tests/num/mod.rs @@ -205,8 +205,6 @@ test_impl_from! { test_u32f64, u32, f64 } // Float -> Float #[test] fn test_f32f64() { - use core::f32; - let max: f64 = f32::MAX.into(); assert_eq!(max as f32, f32::MAX); assert!(max.is_normal()); @@ -704,5 +702,5 @@ macro_rules! test_float { }; } -test_float!(f32, f32, ::core::f32::INFINITY, ::core::f32::NEG_INFINITY, ::core::f32::NAN); -test_float!(f64, f64, ::core::f64::INFINITY, ::core::f64::NEG_INFINITY, ::core::f64::NAN); +test_float!(f32, f32, f32::INFINITY, f32::NEG_INFINITY, f32::NAN); +test_float!(f64, f64, f64::INFINITY, f64::NEG_INFINITY, f64::NAN); diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs index 43eb498d26a..3c83f0f2300 100644 --- a/src/libcore/tests/ops.rs +++ b/src/libcore/tests/ops.rs @@ -61,25 +61,23 @@ fn test_range_inclusive() { #[test] fn test_range_is_empty() { - use core::f32::*; - assert!(!(0.0..10.0).is_empty()); assert!((-0.0..0.0).is_empty()); assert!((10.0..0.0).is_empty()); - assert!(!(NEG_INFINITY..INFINITY).is_empty()); - assert!((EPSILON..NAN).is_empty()); - assert!((NAN..EPSILON).is_empty()); - assert!((NAN..NAN).is_empty()); + assert!(!(f32::NEG_INFINITY..f32::INFINITY).is_empty()); + assert!((f32::EPSILON..f32::NAN).is_empty()); + assert!((f32::NAN..f32::EPSILON).is_empty()); + assert!((f32::NAN..f32::NAN).is_empty()); assert!(!(0.0..=10.0).is_empty()); assert!(!(-0.0..=0.0).is_empty()); assert!((10.0..=0.0).is_empty()); - assert!(!(NEG_INFINITY..=INFINITY).is_empty()); - assert!((EPSILON..=NAN).is_empty()); - assert!((NAN..=EPSILON).is_empty()); - assert!((NAN..=NAN).is_empty()); + assert!(!(f32::NEG_INFINITY..=f32::INFINITY).is_empty()); + assert!((f32::EPSILON..=f32::NAN).is_empty()); + assert!((f32::NAN..=f32::EPSILON).is_empty()); + assert!((f32::NAN..=f32::NAN).is_empty()); } #[test] diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index dbab433e33f..ee8931bf2e7 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -1709,7 +1709,7 @@ fn test_is_sorted() { assert!(![1, 3, 2].is_sorted()); assert!([0].is_sorted()); assert!(empty.is_sorted()); - assert!(![0.0, 1.0, std::f32::NAN].is_sorted()); + assert!(![0.0, 1.0, f32::NAN].is_sorted()); assert!([-2, -1, 0, 3].is_sorted()); assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs())); assert!(!["c", "bb", "aaa"].is_sorted()); diff --git a/src/libcore/tests/tuple.rs b/src/libcore/tests/tuple.rs index 3a2914698cc..ea1e281425c 100644 --- a/src/libcore/tests/tuple.rs +++ b/src/libcore/tests/tuple.rs @@ -1,5 +1,4 @@ use std::cmp::Ordering::{Equal, Greater, Less}; -use std::f64::NAN; #[test] fn test_clone() { @@ -34,12 +33,12 @@ fn test_partial_ord() { assert!(big >= small); assert!(big >= big); - assert!(!((1.0f64, 2.0f64) < (NAN, 3.0))); - assert!(!((1.0f64, 2.0f64) <= (NAN, 3.0))); - assert!(!((1.0f64, 2.0f64) > (NAN, 3.0))); - assert!(!((1.0f64, 2.0f64) >= (NAN, 3.0))); - assert!(((1.0f64, 2.0f64) < (2.0, NAN))); - assert!(!((2.0f64, 2.0f64) < (2.0, NAN))); + assert!(!((1.0f64, 2.0f64) < (f64::NAN, 3.0))); + assert!(!((1.0f64, 2.0f64) <= (f64::NAN, 3.0))); + assert!(!((1.0f64, 2.0f64) > (f64::NAN, 3.0))); + assert!(!((1.0f64, 2.0f64) >= (f64::NAN, 3.0))); + assert!(((1.0f64, 2.0f64) < (2.0, f64::NAN))); + assert!(!((2.0f64, 2.0f64) < (2.0, f64::NAN))); } #[test] From ebcf1e7b73cc60e4a1577968302eecf4c20fbe74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Mon, 6 Apr 2020 22:45:29 +0200 Subject: [PATCH 11/20] Stop importing float module in libserialize --- src/libserialize/json.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 1f9d43cb930..cacc28b6e60 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -198,7 +198,7 @@ use std::num::FpCategory as Fp; use std::ops::Index; use std::str::FromStr; use std::string; -use std::{char, f64, fmt, str}; +use std::{char, fmt, str}; use crate::Encodable; From 09b5d666a075e381a2d8f99e5b7a6695ab9b6259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Mon, 6 Apr 2020 22:45:44 +0200 Subject: [PATCH 12/20] Stop importing float module in libtest --- src/libtest/stats/tests.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libtest/stats/tests.rs b/src/libtest/stats/tests.rs index 5bfd1d3885f..3a6e8401bf1 100644 --- a/src/libtest/stats/tests.rs +++ b/src/libtest/stats/tests.rs @@ -2,7 +2,6 @@ use super::*; extern crate test; use self::test::test::Bencher; -use std::f64; use std::io; use std::io::prelude::*; From e4fc04b6df93785e935ec776705803e6b50e2c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Mon, 6 Apr 2020 23:07:38 +0200 Subject: [PATCH 13/20] Use usize::MAX as assoc const in liballoc --- src/liballoc/raw_vec.rs | 2 +- src/liballoc/tests/btree/map.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 7ac67870eb7..0780b33e53a 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -608,7 +608,7 @@ unsafe impl<#[may_dangle] T, A: AllocRef> Drop for RawVec { #[inline] fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> { - if mem::size_of::() < 8 && alloc_size > core::isize::MAX as usize { + if mem::size_of::() < 8 && alloc_size > isize::MAX as usize { Err(CapacityOverflow) } else { Ok(()) diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs index 14f12ca2d77..96b6c32a1fa 100644 --- a/src/liballoc/tests/btree/map.rs +++ b/src/liballoc/tests/btree/map.rs @@ -475,7 +475,7 @@ fn test_range_large() { #[test] fn test_range_inclusive_max_value() { - let max = std::usize::MAX; + let max = usize::MAX; let map: BTreeMap<_, _> = vec![(max, 0)].into_iter().collect(); assert_eq!(map.range(max..=max).collect::>(), &[(&max, &0)]); From 3e4396b8b5f8a494272ea520e528c22da1ae0888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Mon, 6 Apr 2020 23:08:12 +0200 Subject: [PATCH 14/20] Use integer assoc consts in libcore --- src/libcore/tests/slice.rs | 4 ++-- src/libcore/tests/time.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index ee8931bf2e7..9b9420cc13f 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -1108,14 +1108,14 @@ mod slice_index { // note: using 0 specifically ensures that the result of overflowing is 0..0, // so that `get` doesn't simply return None for the wrong reason. - bad: data[0 ..= ::std::usize::MAX]; + bad: data[0 ..= usize::MAX]; message: "maximum usize"; } in mod rangetoinclusive_overflow { data: [0, 1]; - bad: data[..= ::std::usize::MAX]; + bad: data[..= usize::MAX]; message: "maximum usize"; } } // panic_cases! diff --git a/src/libcore/tests/time.rs b/src/libcore/tests/time.rs index c1fbdf7df76..7a6675dc82f 100644 --- a/src/libcore/tests/time.rs +++ b/src/libcore/tests/time.rs @@ -14,7 +14,7 @@ fn creation() { #[test] #[should_panic] fn new_overflow() { - let _ = Duration::new(::core::u64::MAX, 1_000_000_000); + let _ = Duration::new(u64::MAX, 1_000_000_000); } #[test] @@ -86,7 +86,7 @@ fn checked_add() { Duration::new(0, 500_000_000).checked_add(Duration::new(0, 500_000_001)), Some(Duration::new(1, 1)) ); - assert_eq!(Duration::new(1, 0).checked_add(Duration::new(::core::u64::MAX, 0)), None); + assert_eq!(Duration::new(1, 0).checked_add(Duration::new(u64::MAX, 0)), None); } #[test] @@ -133,7 +133,7 @@ fn checked_mul() { assert_eq!(Duration::new(1, 1).checked_mul(3), Some(Duration::new(3, 3))); assert_eq!(Duration::new(0, 500_000_001).checked_mul(4), Some(Duration::new(2, 4))); assert_eq!(Duration::new(0, 500_000_001).checked_mul(4000), Some(Duration::new(2000, 4000))); - assert_eq!(Duration::new(::core::u64::MAX - 1, 0).checked_mul(2), None); + assert_eq!(Duration::new(u64::MAX - 1, 0).checked_mul(2), None); } #[test] From 68b1af66244bf3486dea3f23d7b90bf410032230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Mon, 6 Apr 2020 23:08:46 +0200 Subject: [PATCH 15/20] Don't import integer module in libstd --- src/libstd/collections/hash/map.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 44f8e8bd171..d1cb8e92d56 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2617,7 +2617,6 @@ mod test_map { use crate::cell::RefCell; use rand::{thread_rng, Rng}; use realstd::collections::TryReserveError::*; - use realstd::usize; // https://github.com/rust-lang/rust/issues/62301 fn _assert_hashmap_is_unwind_safe() { From cf8df0157ac0e537b4948d7487bb50519464ecc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Mon, 6 Apr 2020 23:09:17 +0200 Subject: [PATCH 16/20] Use assoc integer constants in libserialize --- src/libserialize/tests/opaque.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libserialize/tests/opaque.rs b/src/libserialize/tests/opaque.rs index aa099bb8a36..a6ec1580aca 100644 --- a/src/libserialize/tests/opaque.rs +++ b/src/libserialize/tests/opaque.rs @@ -53,7 +53,7 @@ fn test_unit() { #[test] fn test_u8() { let mut vec = vec![]; - for i in ::std::u8::MIN..::std::u8::MAX { + for i in u8::MIN..u8::MAX { vec.push(i); } check_round_trip(vec); @@ -61,30 +61,30 @@ fn test_u8() { #[test] fn test_u16() { - for i in ::std::u16::MIN..::std::u16::MAX { + for i in u16::MIN..u16::MAX { check_round_trip(vec![1, 2, 3, i, i, i]); } } #[test] fn test_u32() { - check_round_trip(vec![1, 2, 3, ::std::u32::MIN, 0, 1, ::std::u32::MAX, 2, 1]); + check_round_trip(vec![1, 2, 3, u32::MIN, 0, 1, u32::MAX, 2, 1]); } #[test] fn test_u64() { - check_round_trip(vec![1, 2, 3, ::std::u64::MIN, 0, 1, ::std::u64::MAX, 2, 1]); + check_round_trip(vec![1, 2, 3, u64::MIN, 0, 1, u64::MAX, 2, 1]); } #[test] fn test_usize() { - check_round_trip(vec![1, 2, 3, ::std::usize::MIN, 0, 1, ::std::usize::MAX, 2, 1]); + check_round_trip(vec![1, 2, 3, usize::MIN, 0, 1, usize::MAX, 2, 1]); } #[test] fn test_i8() { let mut vec = vec![]; - for i in ::std::i8::MIN..::std::i8::MAX { + for i in i8::MIN..i8::MAX { vec.push(i); } check_round_trip(vec); @@ -92,24 +92,24 @@ fn test_i8() { #[test] fn test_i16() { - for i in ::std::i16::MIN..::std::i16::MAX { + for i in i16::MIN..i16::MAX { check_round_trip(vec![-1, 2, -3, i, i, i, 2]); } } #[test] fn test_i32() { - check_round_trip(vec![-1, 2, -3, ::std::i32::MIN, 0, 1, ::std::i32::MAX, 2, 1]); + check_round_trip(vec![-1, 2, -3, i32::MIN, 0, 1, i32::MAX, 2, 1]); } #[test] fn test_i64() { - check_round_trip(vec![-1, 2, -3, ::std::i64::MIN, 0, 1, ::std::i64::MAX, 2, 1]); + check_round_trip(vec![-1, 2, -3, i64::MIN, 0, 1, i64::MAX, 2, 1]); } #[test] fn test_isize() { - check_round_trip(vec![-1, 2, -3, ::std::isize::MIN, 0, 1, ::std::isize::MAX, 2, 1]); + check_round_trip(vec![-1, 2, -3, isize::MIN, 0, 1, isize::MAX, 2, 1]); } #[test] From f7778d36c7246622c4c2330183f68cb9afd08c62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Mon, 6 Apr 2020 23:09:56 +0200 Subject: [PATCH 17/20] Use assoc integer constants in librustc_* --- src/librustc_codegen_ssa/back/write.rs | 2 +- src/librustc_codegen_ssa/base.rs | 2 +- src/librustc_errors/emitter.rs | 10 +++++----- src/librustc_index/bit_set.rs | 2 +- src/librustc_trait_selection/traits/object_safety.rs | 2 +- src/librustc_trait_selection/traits/select.rs | 8 ++------ src/librustc_typeck/collect.rs | 4 ++-- .../rfc-2627-raw-dylib/link-ordinal-too-large.stderr | 2 +- 8 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 35c5812e1f3..ca349a7890a 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -1528,7 +1528,7 @@ fn start_executing_work( } } -pub const CODEGEN_WORKER_ID: usize = ::std::usize::MAX; +pub const CODEGEN_WORKER_ID: usize = usize::MAX; /// `FatalError` is explicitly not `Send`. #[must_use] diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 02974151555..8bd4ffd0a56 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -507,7 +507,7 @@ fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } } -pub const CODEGEN_WORKER_ID: usize = ::std::usize::MAX; +pub const CODEGEN_WORKER_ID: usize = usize::MAX; pub fn codegen_crate( backend: B, diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 3a7e108ddaf..3f5738a93a9 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -1361,7 +1361,7 @@ impl EmitterWriter { let mut multilines = FxHashMap::default(); // Get the left-side margin to remove it - let mut whitespace_margin = std::usize::MAX; + let mut whitespace_margin = usize::MAX; for line_idx in 0..annotated_file.lines.len() { let file = annotated_file.file.clone(); let line = &annotated_file.lines[line_idx]; @@ -1373,19 +1373,19 @@ impl EmitterWriter { } } } - if whitespace_margin == std::usize::MAX { + if whitespace_margin == usize::MAX { whitespace_margin = 0; } // Left-most column any visible span points at. - let mut span_left_margin = std::usize::MAX; + let mut span_left_margin = usize::MAX; for line in &annotated_file.lines { for ann in &line.annotations { span_left_margin = min(span_left_margin, ann.start_col); span_left_margin = min(span_left_margin, ann.end_col); } } - if span_left_margin == std::usize::MAX { + if span_left_margin == usize::MAX { span_left_margin = 0; } @@ -1421,7 +1421,7 @@ impl EmitterWriter { } else { termize::dimensions() .map(|(w, _)| w.saturating_sub(code_offset)) - .unwrap_or(std::usize::MAX) + .unwrap_or(usize::MAX) }; let margin = Margin::new( diff --git a/src/librustc_index/bit_set.rs b/src/librustc_index/bit_set.rs index 2a1a5607672..46c38840516 100644 --- a/src/librustc_index/bit_set.rs +++ b/src/librustc_index/bit_set.rs @@ -307,7 +307,7 @@ impl<'a, T: Idx> BitIter<'a, T> { // additional state about whether we have started. BitIter { word: 0, - offset: std::usize::MAX - (WORD_BITS - 1), + offset: usize::MAX - (WORD_BITS - 1), iter: words.iter(), marker: PhantomData, } diff --git a/src/librustc_trait_selection/traits/object_safety.rs b/src/librustc_trait_selection/traits/object_safety.rs index 20b3fa908d2..a4c5ec2f17e 100644 --- a/src/librustc_trait_selection/traits/object_safety.rs +++ b/src/librustc_trait_selection/traits/object_safety.rs @@ -616,7 +616,7 @@ fn receiver_is_dispatchable<'tcx>( // FIXME(mikeyhew) this is a total hack. Once object_safe_for_dispatch is stabilized, we can // replace this with `dyn Trait` let unsized_self_ty: Ty<'tcx> = - tcx.mk_ty_param(::std::u32::MAX, Symbol::intern("RustaceansAreAwesome")); + tcx.mk_ty_param(u32::MAX, Symbol::intern("RustaceansAreAwesome")); // `Receiver[Self => U]` let unsized_receiver_ty = diff --git a/src/librustc_trait_selection/traits/select.rs b/src/librustc_trait_selection/traits/select.rs index 3d95824cdf0..827792585e3 100644 --- a/src/librustc_trait_selection/traits/select.rs +++ b/src/librustc_trait_selection/traits/select.rs @@ -3625,11 +3625,7 @@ struct ProvisionalEvaluation { impl<'tcx> Default for ProvisionalEvaluationCache<'tcx> { fn default() -> Self { - Self { - dfn: Cell::new(0), - reached_depth: Cell::new(std::usize::MAX), - map: Default::default(), - } + Self { dfn: Cell::new(0), reached_depth: Cell::new(usize::MAX), map: Default::default() } } } @@ -3728,7 +3724,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> { op(fresh_trait_ref, eval.result); } - self.reached_depth.set(std::usize::MAX); + self.reached_depth.set(usize::MAX); } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 13c6670f6b2..c5e9a288c9c 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2620,13 +2620,13 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option { _ => None, }; if let Some(Lit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) = sole_meta_list { - if *ordinal <= std::usize::MAX as u128 { + if *ordinal <= usize::MAX as u128 { Some(*ordinal as usize) } else { let msg = format!("ordinal value in `link_ordinal` is too large: `{}`", &ordinal); tcx.sess .struct_span_err(attr.span, &msg) - .note("the value may not exceed `std::usize::MAX`") + .note("the value may not exceed `usize::MAX`") .emit(); None } diff --git a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr index b3b22f9776d..b9b877aa056 100644 --- a/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr +++ b/src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr @@ -12,7 +12,7 @@ error: ordinal value in `link_ordinal` is too large: `18446744073709551616` LL | #[link_ordinal(18446744073709551616)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: the value may not exceed `std::usize::MAX` + = note: the value may not exceed `usize::MAX` error: aborting due to previous error From e8339e820b0c4e7c9a26a3e3495b7655e60bd102 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 20 Mar 2020 15:28:26 -0700 Subject: [PATCH 18/20] Use split_at in slice's ToOwned::clone_into It appears to codegen slightly more efficiently with `split_at` taking two slices at once, rather than slicing across different calls. --- src/liballoc/slice.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index a3d9c78b7f5..cd750d25580 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -733,14 +733,14 @@ impl ToOwned for [T] { fn clone_into(&self, target: &mut Vec) { // drop anything in target that will not be overwritten target.truncate(self.len()); - let len = target.len(); - - // reuse the contained values' allocations/resources. - target.clone_from_slice(&self[..len]); // target.len <= self.len due to the truncate above, so the - // slice here is always in-bounds. - target.extend_from_slice(&self[len..]); + // slices here are always in-bounds. + let (init, tail) = self.split_at(target.len()); + + // reuse the contained values' allocations/resources. + target.clone_from_slice(init); + target.extend_from_slice(tail); } } From b80fa76ee0a160fffa04e337b8e33ef655a80649 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 20 Mar 2020 15:42:56 -0700 Subject: [PATCH 19/20] Implement ToOwned::clone_into for CStr It can try to keep its allocation by converting the inner `Box` to `Vec`, using `clone_into` on the bytes, then convert back to `Box`. --- src/libstd/ffi/c_str.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 04eaba515ff..0a4802fb2c8 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -1329,6 +1329,12 @@ impl ToOwned for CStr { fn to_owned(&self) -> CString { CString { inner: self.to_bytes_with_nul().into() } } + + fn clone_into(&self, target: &mut CString) { + let mut b = Vec::from(mem::take(&mut target.inner)); + self.to_bytes_with_nul().clone_into(&mut b); + target.inner = b.into_boxed_slice(); + } } #[stable(feature = "cstring_asref", since = "1.7.0")] @@ -1510,6 +1516,17 @@ mod tests { assert_eq!(boxed.to_bytes_with_nul(), &[0]); } + #[test] + fn test_c_str_clone_into() { + let mut c_string = CString::new("lorem").unwrap(); + let c_ptr = c_string.as_ptr(); + let c_str = CStr::from_bytes_with_nul(b"ipsum\0").unwrap(); + c_str.clone_into(&mut c_string); + assert_eq!(c_str, c_string.as_c_str()); + // The exact same size shouldn't have needed to move its allocation + assert_eq!(c_ptr, c_string.as_ptr()); + } + #[test] fn into_rc() { let orig: &[u8] = b"Hello, world!\0"; From f854070bb820501d88d1b029660bfde663595530 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 20 Mar 2020 15:46:40 -0700 Subject: [PATCH 20/20] Forward OsStr::clone_into to the inner Vec Despite OS differences, they're all just `Vec` inside, so we can just forward `clone_into` calls to that optimized implementation. --- src/libstd/ffi/os_str.rs | 3 +-- src/libstd/sys/windows/os_str.rs | 4 ++++ src/libstd/sys_common/os_str_bytes.rs | 4 ++++ src/libstd/sys_common/wtf8.rs | 4 ++++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 5e686946f8e..4fde3316973 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -1120,8 +1120,7 @@ impl ToOwned for OsStr { self.to_os_string() } fn clone_into(&self, target: &mut OsString) { - target.clear(); - target.push(self); + self.inner.clone_into(&mut target.inner) } } diff --git a/src/libstd/sys/windows/os_str.rs b/src/libstd/sys/windows/os_str.rs index 6aab028873e..2f5fc72ab44 100644 --- a/src/libstd/sys/windows/os_str.rs +++ b/src/libstd/sys/windows/os_str.rs @@ -159,6 +159,10 @@ impl Slice { Buf { inner: buf } } + pub fn clone_into(&self, buf: &mut Buf) { + self.inner.clone_into(&mut buf.inner) + } + #[inline] pub fn into_box(&self) -> Box { unsafe { mem::transmute(self.inner.into_box()) } diff --git a/src/libstd/sys_common/os_str_bytes.rs b/src/libstd/sys_common/os_str_bytes.rs index aa6cc33d831..984c032e2a3 100644 --- a/src/libstd/sys_common/os_str_bytes.rs +++ b/src/libstd/sys_common/os_str_bytes.rs @@ -173,6 +173,10 @@ impl Slice { Buf { inner: self.inner.to_vec() } } + pub fn clone_into(&self, buf: &mut Buf) { + self.inner.clone_into(&mut buf.inner) + } + #[inline] pub fn into_box(&self) -> Box { let boxed: Box<[u8]> = self.inner.into(); diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs index fc6614552a9..a98407da448 100644 --- a/src/libstd/sys_common/wtf8.rs +++ b/src/libstd/sys_common/wtf8.rs @@ -613,6 +613,10 @@ impl Wtf8 { } } + pub fn clone_into(&self, buf: &mut Wtf8Buf) { + self.bytes.clone_into(&mut buf.bytes) + } + /// Boxes this `Wtf8`. #[inline] pub fn into_box(&self) -> Box {