diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 3f50c68e3ebf5..066a61a7a7b53 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -155,8 +155,7 @@ pub fn run_compiler( ), } } - let diagnostic_output = - emitter.map(|emitter| DiagnosticOutput::Raw(emitter)).unwrap_or(DiagnosticOutput::Default); + let diagnostic_output = emitter.map_or(DiagnosticOutput::Default, DiagnosticOutput::Raw); let matches = match handle_options(&args) { Some(matches) => matches, None => return Ok(()), diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index e7cb8cb6e8876..925f1bd33cb7a 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1861,7 +1861,7 @@ where } if *self == DUMMY_SP { - std::hash::Hash::hash(&TAG_INVALID_SPAN, hasher); + Hash::hash(&TAG_INVALID_SPAN, hasher); return; } @@ -1872,28 +1872,28 @@ where let (file_lo, line_lo, col_lo) = match ctx.byte_pos_to_line_and_col(span.lo) { Some(pos) => pos, None => { - std::hash::Hash::hash(&TAG_INVALID_SPAN, hasher); + Hash::hash(&TAG_INVALID_SPAN, hasher); span.ctxt.hash_stable(ctx, hasher); return; } }; if !file_lo.contains(span.hi) { - std::hash::Hash::hash(&TAG_INVALID_SPAN, hasher); + Hash::hash(&TAG_INVALID_SPAN, hasher); span.ctxt.hash_stable(ctx, hasher); return; } - std::hash::Hash::hash(&TAG_VALID_SPAN, hasher); + Hash::hash(&TAG_VALID_SPAN, hasher); // We truncate the stable ID hash and line and column numbers. The chances // of causing a collision this way should be minimal. - std::hash::Hash::hash(&(file_lo.name_hash as u64), hasher); + Hash::hash(&(file_lo.name_hash as u64), hasher); let col = (col_lo.0 as u64) & 0xFF; let line = ((line_lo as u64) & 0xFF_FF_FF) << 8; let len = ((span.hi - span.lo).0 as u64) << 32; let line_col_len = col | line | len; - std::hash::Hash::hash(&line_col_len, hasher); + Hash::hash(&line_col_len, hasher); span.ctxt.hash_stable(ctx, hasher); } } diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index 66975f32a1f4a..2f3fb49717b9c 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -2,6 +2,7 @@ use super::method::MethodCallee; use super::FnCtxt; +use rustc_ast as ast; use rustc_errors::{self, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; @@ -13,6 +14,7 @@ use rustc_middle::ty::TyKind::{Adt, Array, Char, FnDef, Never, Ref, Str, Tuple, use rustc_middle::ty::{ self, suggest_constraining_type_param, Ty, TyCtxt, TypeFoldable, TypeVisitor, }; +use rustc_span::source_map::Spanned; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use rustc_trait_selection::infer::InferCtxtExt; @@ -673,6 +675,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match actual.kind() { Uint(_) if op == hir::UnOp::UnNeg => { err.note("unsigned values cannot be negated"); + + if let hir::ExprKind::Unary( + _, + hir::Expr { + kind: + hir::ExprKind::Lit(Spanned { + node: ast::LitKind::Int(1, _), + .. + }), + .. + }, + ) = ex.kind + { + err.span_suggestion( + ex.span, + &format!( + "you may have meant the maximum value of `{}`", + actual + ), + format!("{}::MAX", actual), + Applicability::MaybeIncorrect, + ); + } } Str | Never | Char | Tuple(_) | Array(_, _) => {} Ref(_, ref lty, _) if *lty.kind() == Str => {} diff --git a/config.toml.example b/config.toml.example index c5efb8ed5e51c..6dc9eccbdfceb 100644 --- a/config.toml.example +++ b/config.toml.example @@ -382,6 +382,10 @@ changelog-seen = 1 # Overrides the `debug-assertions` option, if defined. # # Defaults to rust.debug-assertions value +# +# If you see a message from `tracing` saying +# `max_level_info` is enabled and means logging won't be shown, +# set this value to `true`. #debug-logging = debug-assertions # Debuginfo level for most of Rust code, corresponds to the `-C debuginfo=N` option of `rustc`. diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 04f317401f15d..606bf94f99867 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -1783,6 +1783,10 @@ impl<'a, K: 'a, V: 'a> DrainFilterInner<'a, K, V> { /// Implementation of a typical `DrainFilter::size_hint` method. pub(super) fn size_hint(&self) -> (usize, Option) { + // In most of the btree iterators, `self.length` is the number of elements + // yet to be visited. Here, it includes elements that were visited and that + // the predicate decided not to drain. Making this upper bound more accurate + // requires maintaining an extra field and is not worth while. (0, Some(*self.length)) } } diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs index e8f5a6f429486..a01ebb316e886 100644 --- a/library/std/src/sync/mutex.rs +++ b/library/std/src/sync/mutex.rs @@ -276,7 +276,7 @@ impl Mutex { /// # Errors /// /// If another user of this mutex panicked while holding the mutex, then - /// this call will return failure if the mutex would otherwise be + /// this call will return an error if the mutex would otherwise be /// acquired. /// /// # Examples diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 566ac0920dc8f..9e37108c88724 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -183,7 +183,6 @@ struct InnerReadDir { root: PathBuf, } -#[derive(Clone)] pub struct ReadDir { inner: Arc, end_of_stream: bool, @@ -196,7 +195,7 @@ unsafe impl Sync for Dir {} pub struct DirEntry { entry: dirent64, - dir: ReadDir, + dir: Arc, // We need to store an owned copy of the entry name // on Solaris and Fuchsia because a) it uses a zero-length // array to store the name, b) its lifetime between readdir @@ -443,7 +442,7 @@ impl Iterator for ReadDir { name: slice::from_raw_parts(name as *const u8, namelen as usize) .to_owned() .into_boxed_slice(), - dir: self.clone(), + dir: Arc::clone(&self.inner), }; if ret.name_bytes() != b"." && ret.name_bytes() != b".." { return Some(Ok(ret)); @@ -464,7 +463,7 @@ impl Iterator for ReadDir { } unsafe { - let mut ret = DirEntry { entry: mem::zeroed(), dir: self.clone() }; + let mut ret = DirEntry { entry: mem::zeroed(), dir: Arc::clone(&self.inner) }; let mut entry_ptr = ptr::null_mut(); loop { if readdir64_r(self.inner.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 { @@ -497,7 +496,7 @@ impl Drop for Dir { impl DirEntry { pub fn path(&self) -> PathBuf { - self.dir.inner.root.join(OsStr::from_bytes(self.name_bytes())) + self.dir.root.join(OsStr::from_bytes(self.name_bytes())) } pub fn file_name(&self) -> OsString { @@ -506,7 +505,7 @@ impl DirEntry { #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "android"))] pub fn metadata(&self) -> io::Result { - let fd = cvt(unsafe { dirfd(self.dir.inner.dirp.0) })?; + let fd = cvt(unsafe { dirfd(self.dir.dirp.0) })?; let name = self.entry.d_name.as_ptr(); cfg_has_statx! { diff --git a/library/std/src/sys/vxworks/fs.rs b/library/std/src/sys/vxworks/fs.rs index 557e65ca01b1c..cb761af1a25c2 100644 --- a/library/std/src/sys/vxworks/fs.rs +++ b/library/std/src/sys/vxworks/fs.rs @@ -27,7 +27,6 @@ struct InnerReadDir { root: PathBuf, } -#[derive(Clone)] pub struct ReadDir { inner: Arc, end_of_stream: bool, @@ -40,7 +39,7 @@ unsafe impl Sync for Dir {} pub struct DirEntry { entry: dirent, - dir: ReadDir, + dir: Arc, } #[derive(Clone, Debug)] @@ -170,7 +169,7 @@ impl Iterator for ReadDir { } unsafe { - let mut ret = DirEntry { entry: mem::zeroed(), dir: self.clone() }; + let mut ret = DirEntry { entry: mem::zeroed(), dir: Arc::clone(&self.inner) }; let mut entry_ptr = ptr::null_mut(); loop { if readdir64_r(self.inner.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 { @@ -204,7 +203,7 @@ impl Drop for Dir { impl DirEntry { pub fn path(&self) -> PathBuf { use crate::sys::vxworks::ext::ffi::OsStrExt; - self.dir.inner.root.join(OsStr::from_bytes(self.name_bytes())) + self.dir.root.join(OsStr::from_bytes(self.name_bytes())) } pub fn file_name(&self) -> OsString { diff --git a/src/test/compile-fail/issue-27675-unchecked-bounds.rs b/src/test/compile-fail/issue-27675-unchecked-bounds.rs new file mode 100644 index 0000000000000..1cfc230453120 --- /dev/null +++ b/src/test/compile-fail/issue-27675-unchecked-bounds.rs @@ -0,0 +1,19 @@ +/// The compiler previously did not properly check the bound of `From` when it was used from type +/// of the dyn trait object (use in `copy_any` below). Since the associated type is under user +/// control in this usage, the compiler could be tricked to believe any type implemented any trait. +/// This would ICE, except for pure marker traits like `Copy`. It did not require providing an +/// instance of the dyn trait type, only name said type. +trait Setup { + type From: Copy; +} + +fn copy(from: &U::From) -> U::From { + *from +} + +pub fn copy_any(t: &T) -> T { + copy::>(t) + //~^ ERROR the trait bound `T: Copy` is not satisfied +} + +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-negate-unsigned.stderr b/src/test/ui/feature-gates/feature-gate-negate-unsigned.stderr index aa84c27e40f5e..d1f4ed5cb04b8 100644 --- a/src/test/ui/feature-gates/feature-gate-negate-unsigned.stderr +++ b/src/test/ui/feature-gates/feature-gate-negate-unsigned.stderr @@ -2,7 +2,10 @@ error[E0600]: cannot apply unary operator `-` to type `usize` --> $DIR/feature-gate-negate-unsigned.rs:10:23 | LL | let _max: usize = -1; - | ^^ cannot apply unary operator `-` + | ^^ + | | + | cannot apply unary operator `-` + | help: you may have meant the maximum value of `usize`: `usize::MAX` | = note: unsigned values cannot be negated diff --git a/src/test/ui/unsigned-literal-negation.rs b/src/test/ui/unsigned-literal-negation.rs new file mode 100644 index 0000000000000..943c7f79742ab --- /dev/null +++ b/src/test/ui/unsigned-literal-negation.rs @@ -0,0 +1,5 @@ +fn main() { + let x = -1 as usize; //~ ERROR: cannot apply unary operator `-` + let x = (-1) as usize; //~ ERROR: cannot apply unary operator `-` + let x: u32 = -1; //~ ERROR: cannot apply unary operator `-` +} diff --git a/src/test/ui/unsigned-literal-negation.stderr b/src/test/ui/unsigned-literal-negation.stderr new file mode 100644 index 0000000000000..0aaa8c3b72f9d --- /dev/null +++ b/src/test/ui/unsigned-literal-negation.stderr @@ -0,0 +1,36 @@ +error[E0600]: cannot apply unary operator `-` to type `usize` + --> $DIR/unsigned-literal-negation.rs:2:13 + | +LL | let x = -1 as usize; + | ^^ + | | + | cannot apply unary operator `-` + | help: you may have meant the maximum value of `usize`: `usize::MAX` + | + = note: unsigned values cannot be negated + +error[E0600]: cannot apply unary operator `-` to type `usize` + --> $DIR/unsigned-literal-negation.rs:3:13 + | +LL | let x = (-1) as usize; + | ^^^^ + | | + | cannot apply unary operator `-` + | help: you may have meant the maximum value of `usize`: `usize::MAX` + | + = note: unsigned values cannot be negated + +error[E0600]: cannot apply unary operator `-` to type `u32` + --> $DIR/unsigned-literal-negation.rs:4:18 + | +LL | let x: u32 = -1; + | ^^ + | | + | cannot apply unary operator `-` + | help: you may have meant the maximum value of `u32`: `u32::MAX` + | + = note: unsigned values cannot be negated + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0600`.