diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index a922d4f118b..0f2665eba6f 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1023,6 +1023,31 @@ impl RefCell { } } +impl RefCell { + /// Takes the wrapped value, leaving `Default::default()` in its place. + /// + /// # Panics + /// + /// Panics if the value is currently borrowed. + /// + /// # Examples + /// + /// ``` + /// #![feature(refcell_take)] + /// use std::cell::RefCell; + /// + /// let c = RefCell::new(5); + /// let five = c.take(); + /// + /// assert_eq!(five, 5); + /// assert_eq!(c.into_inner(), 0); + /// ``` + #[unstable(feature = "refcell_take", issue = "71395")] + pub fn take(&self) -> T { + self.replace(Default::default()) + } +} + #[stable(feature = "rust1", since = "1.0.0")] unsafe impl Send for RefCell where T: Send {} diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index bf4a6c52ab8..e01412bc21c 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -281,6 +281,7 @@ E0535: include_str!("./error_codes/E0535.md"), E0536: include_str!("./error_codes/E0536.md"), E0537: include_str!("./error_codes/E0537.md"), E0538: include_str!("./error_codes/E0538.md"), +E0539: include_str!("./error_codes/E0539.md"), E0541: include_str!("./error_codes/E0541.md"), E0550: include_str!("./error_codes/E0550.md"), E0551: include_str!("./error_codes/E0551.md"), @@ -570,7 +571,6 @@ E0753: include_str!("./error_codes/E0753.md"), E0521, // borrowed data escapes outside of closure E0523, // E0526, // shuffle indices are not constant - E0539, // incorrect meta item E0540, // multiple rustc_deprecated attributes E0542, // missing 'since' E0543, // missing 'reason' diff --git a/src/librustc_error_codes/error_codes/E0539.md b/src/librustc_error_codes/error_codes/E0539.md new file mode 100644 index 00000000000..df2d7d910bb --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0539.md @@ -0,0 +1,48 @@ +An invalid meta-item was used inside an attribute. + +Erroneous code example: + +```compile_fail,E0539 +#![feature(staged_api)] +#![stable(since = "1.0.0", feature = "test")] + +#[rustc_deprecated(reason)] // error! +#[unstable(feature = "deprecated_fn", issue = "123")] +fn deprecated() {} + +#[unstable(feature = "unstable_struct", issue)] // error! +struct Unstable; + +#[rustc_const_unstable(feature)] // error! +const fn unstable_fn() {} + +#[stable(feature = "stable_struct", since)] // error! +struct Stable; + +#[rustc_const_stable(feature)] // error! +const fn stable_fn() {} +``` + +Meta items are the key-value pairs inside of an attribute. +To fix these issues you need to give required key-value pairs. + +``` +#![feature(staged_api)] +#![stable(since = "1.0.0", feature = "test")] + +#[rustc_deprecated(since = "1.39.0", reason = "reason")] // ok! +#[unstable(feature = "deprecated_fn", issue = "123")] +fn deprecated() {} + +#[unstable(feature = "unstable_struct", issue = "123")] // ok! +struct Unstable; + +#[rustc_const_unstable(feature = "unstable_fn", issue = "124")] // ok! +const fn unstable_fn() {} + +#[stable(feature = "stable_struct", since = "1.39.0")] // ok! +struct Stable; + +#[rustc_const_stable(feature = "stable_fn", since = "1.39.0")] // ok! +const fn stable_fn() {} +``` diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index a9586b74a56..b6991349ff4 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -11,6 +11,7 @@ use std::ops::RangeInclusive; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; +use rustc_middle::mir::interpret::{InterpError, InterpErrorInfo}; use rustc_middle::ty; use rustc_middle::ty::layout::TyAndLayout; use rustc_span::symbol::{sym, Symbol}; @@ -24,43 +25,71 @@ use super::{ }; macro_rules! throw_validation_failure { - ($what:expr, $where:expr, $details:expr) => {{ - let mut msg = format!("encountered {}", $what); - let where_ = &$where; - if !where_.is_empty() { - msg.push_str(" at "); - write_path(&mut msg, where_); - } - write!(&mut msg, ", but expected {}", $details).unwrap(); - throw_ub!(ValidationFailure(msg)) - }}; - ($what:expr, $where:expr) => {{ + ($what:expr, $where:expr $(, $expected:expr )?) => {{ let mut msg = format!("encountered {}", $what); let where_ = &$where; if !where_.is_empty() { msg.push_str(" at "); write_path(&mut msg, where_); } + $( write!(&mut msg, ", but expected {}", $expected).unwrap(); )? throw_ub!(ValidationFailure(msg)) }}; } +/// Returns a validation failure for any Err value of $e. +// FIXME: Replace all usages of try_validation! with try_validation_pat!. macro_rules! try_validation { - ($e:expr, $what:expr, $where:expr, $details:expr) => {{ - match $e { - Ok(x) => x, - // We re-throw the error, so we are okay with allocation: - // this can only slow down builds that fail anyway. - Err(_) => throw_validation_failure!($what, $where, $details), - } + ($e:expr, $what:expr, $where:expr $(, $expected:expr )?) => {{ + try_validation_pat!($e, $where, { + _ => { "{}", $what } $( expected { "{}", $expected } )?, + }) }}; - - ($e:expr, $what:expr, $where:expr) => {{ +} +/// Like try_validation, but will throw a validation error if any of the patterns in $p are +/// matched. Other errors are passed back to the caller, unchanged. This lets you use the patterns +/// as a kind of validation blacklist: +/// +/// ``` +/// let v = try_validation_pat!(some_fn(), some_path, { +/// Foo | Bar | Baz => { "some failure" }, +/// }); +/// // Failures that match $p are thrown up as validation errors, but other errors are passed back +/// // unchanged. +/// ``` +/// +/// An additional expected parameter can also be added to the failure message: +/// +/// ``` +/// let v = try_validation_pat!(some_fn(), some_path, { +/// Foo | Bar | Baz => { "some failure" } expected { "something that wasn't a failure" }, +/// }); +/// ``` +/// +/// An additional nicety is that both parameters actually take format args, so you can just write +/// the format string in directly: +/// +/// ``` +/// let v = try_validation_pat!(some_fn(), some_path, { +/// Foo | Bar | Baz => { "{:?}", some_failure } expected { "{}", expected_value }, +/// }); +/// ``` +/// +macro_rules! try_validation_pat { + ($e:expr, $where:expr, { $( $p:pat )|+ => + { $( $what_fmt:expr ),+ } $( expected { $( $expected_fmt:expr ),+ } )? $( , )?}) => {{ match $e { Ok(x) => x, - // We re-throw the error, so we are okay with allocation: - // this can only slow down builds that fail anyway. - Err(_) => throw_validation_failure!($what, $where), + // We catch the error and turn it into a validation failure. We are okay with + // allocation here as this can only slow down builds that fail anyway. + $( Err(InterpErrorInfo { kind: $p, .. }) )|+ => + throw_validation_failure!( + format_args!($( $what_fmt ),+), + $where + $(, format_args!($( $expected_fmt ),+))? + ), + #[allow(unreachable_patterns)] + Err(e) => Err::(e)?, } }}; } @@ -492,11 +521,9 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' // We are conservative with undef for integers, but try to // actually enforce the strict rules for raw pointers (mostly because // that lets us re-use `ref_to_mplace`). - let place = try_validation!( - self.ecx.ref_to_mplace(self.ecx.read_immediate(value)?), - "uninitialized raw pointer", - self.path - ); + let place = try_validation_pat!(self.ecx.ref_to_mplace(self.ecx.read_immediate(value)?), self.path, { + err_ub!(InvalidUndefBytes(..)) => { "uninitialized raw pointer" }, + }); if place.layout.is_unsized() { self.check_wide_ptr_meta(place.meta, place.layout)?; } @@ -800,7 +827,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> throw_validation_failure!("uninitialized bytes", self.path) } - // Other errors shouldn't be possible + // Propagate upwards (that will also check for unexpected errors). _ => return Err(err), } } @@ -843,9 +870,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Run it. match visitor.visit_value(op) { Ok(()) => Ok(()), - // We should only get validation errors here. Avoid other errors as - // those do not show *where* in the value the issue lies. + // Pass through validation failures. Err(err) if matches!(err.kind, err_ub!(ValidationFailure { .. })) => Err(err), + // Also pass through InvalidProgram, those just indicate that we could not + // validate and each caller will know best what to do with them. + Err(err) if matches!(err.kind, InterpError::InvalidProgram(_)) => Err(err), + // Avoid other errors as those do not show *where* in the value the issue lies. Err(err) => bug!("Unexpected error during validation: {}", err), } } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 2673bab2028..aae80185b4d 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -549,11 +549,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { return None; } - // FIXME we need to revisit this for #67176 - if rvalue.needs_subst() { - return None; - } - // Perform any special handling for specific Rvalue types. // Generally, checks here fall into one of two categories: // 1. Additional checking to provide useful lints to the user @@ -594,6 +589,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { _ => {} } + // FIXME we need to revisit this for #67176 + if rvalue.needs_subst() { + return None; + } + self.use_ecx(|this| { trace!("calling eval_rvalue_into_place(rvalue = {:?}, place = {:?})", rvalue, place); this.ecx.eval_rvalue_into_place(rvalue, place)?; diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index bf36b2cdffe..86cafa0b8ca 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -74,7 +74,7 @@ use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode}; use smallvec::{smallvec, SmallVec}; use std::ops::Deref; -pub struct Coerce<'a, 'tcx> { +struct Coerce<'a, 'tcx> { fcx: &'a FnCtxt<'a, 'tcx>, cause: ObligationCause<'tcx>, use_lub: bool, @@ -126,7 +126,7 @@ fn success<'tcx>( } impl<'f, 'tcx> Coerce<'f, 'tcx> { - pub fn new( + fn new( fcx: &'f FnCtxt<'f, 'tcx>, cause: ObligationCause<'tcx>, allow_two_phase: AllowTwoPhase, @@ -134,7 +134,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { Coerce { fcx, cause, allow_two_phase, use_lub: false } } - pub fn unify(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> { + fn unify(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> { debug!("unify(a: {:?}, b: {:?}, use_lub: {})", a, b, self.use_lub); self.commit_if_ok(|_| { if self.use_lub { @@ -841,6 +841,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.probe(|_| coerce.coerce(source, target)).is_ok() } + /// Given a type and a target type, this function will calculate and return + /// how many dereference steps needed to achieve `expr_ty <: target`. If + /// it's not possible, return `None`. + pub fn deref_steps(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> Option { + let cause = self.cause(rustc_span::DUMMY_SP, ObligationCauseCode::ExprAssignable); + // We don't ever need two-phase here since we throw out the result of the coercion + let coerce = Coerce::new(self, cause, AllowTwoPhase::No); + coerce + .autoderef(rustc_span::DUMMY_SP, expr_ty) + .find_map(|(ty, steps)| coerce.unify(ty, target).ok().map(|_| steps)) + } + /// Given some expressions, their known unified type and another expression, /// tries to unify the types, potentially inserting coercions on any of the /// provided expressions and returns their LUB (aka "common supertype"). diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 65ef9cad874..9e14efb67a9 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -1,4 +1,3 @@ -use crate::check::coercion::Coerce; use crate::check::FnCtxt; use rustc_infer::infer::InferOk; use rustc_trait_selection::infer::InferCtxtExt as _; @@ -9,7 +8,6 @@ use rustc_ast::util::parser::PREC_POSTFIX; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::{is_range_literal, Node}; -use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::{self, AssocItem, Ty, TypeAndMut}; use rustc_span::symbol::sym; @@ -355,6 +353,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { false } + fn replace_prefix(&self, s: A, old: B, new: C) -> Option + where + A: AsRef, + B: AsRef, + C: AsRef, + { + let s = s.as_ref(); + let old = old.as_ref(); + if s.starts_with(old) { Some(new.as_ref().to_owned() + &s[old.len()..]) } else { None } + } + /// This function is used to determine potential "simple" improvements or users' errors and /// provide them useful help. For example: /// @@ -376,7 +385,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'_>, checked_ty: Ty<'tcx>, expected: Ty<'tcx>, - ) -> Option<(Span, &'static str, String)> { + ) -> Option<(Span, &'static str, String, Applicability)> { let sm = self.sess().source_map(); let sp = expr.span; if sm.is_imported(sp) { @@ -400,11 +409,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (&ty::Str, &ty::Array(arr, _) | &ty::Slice(arr)) if arr == self.tcx.types.u8 => { if let hir::ExprKind::Lit(_) = expr.kind { if let Ok(src) = sm.span_to_snippet(sp) { - if src.starts_with("b\"") { + if let Some(src) = self.replace_prefix(src, "b\"", "\"") { return Some(( sp, "consider removing the leading `b`", - src[1..].to_string(), + src, + Applicability::MachineApplicable, )); } } @@ -413,11 +423,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (&ty::Array(arr, _) | &ty::Slice(arr), &ty::Str) if arr == self.tcx.types.u8 => { if let hir::ExprKind::Lit(_) = expr.kind { if let Ok(src) = sm.span_to_snippet(sp) { - if src.starts_with('"') { + if let Some(src) = self.replace_prefix(src, "\"", "b\"") { return Some(( sp, "consider adding a leading `b`", - format!("b{}", src), + src, + Applicability::MachineApplicable, )); } } @@ -470,7 +481,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let sugg_expr = if needs_parens { format!("({})", src) } else { src }; if let Some(sugg) = self.can_use_as_ref(expr) { - return Some(sugg); + return Some(( + sugg.0, + sugg.1, + sugg.2, + Applicability::MachineApplicable, + )); } let field_name = if is_struct_pat_shorthand_field { format!("{}: ", sugg_expr) @@ -495,6 +511,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "consider dereferencing here to assign to the mutable \ borrowed piece of memory", format!("*{}", src), + Applicability::MachineApplicable, )); } } @@ -505,11 +522,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sp, "consider mutably borrowing here", format!("{}&mut {}", field_name, sugg_expr), + Applicability::MachineApplicable, ), hir::Mutability::Not => ( sp, "consider borrowing here", format!("{}&{}", field_name, sugg_expr), + Applicability::MachineApplicable, ), }); } @@ -526,51 +545,88 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We have `&T`, check if what was expected was `T`. If so, // we may want to suggest removing a `&`. if sm.is_imported(expr.span) { - if let Ok(code) = sm.span_to_snippet(sp) { - if code.starts_with('&') { + if let Ok(src) = sm.span_to_snippet(sp) { + if let Some(src) = self.replace_prefix(src, "&", "") { return Some(( sp, "consider removing the borrow", - code[1..].to_string(), + src, + Applicability::MachineApplicable, )); } } return None; } if let Ok(code) = sm.span_to_snippet(expr.span) { - return Some((sp, "consider removing the borrow", code)); + return Some(( + sp, + "consider removing the borrow", + code, + Applicability::MachineApplicable, + )); } } ( _, - &ty::RawPtr(TypeAndMut { ty: _, mutbl: hir::Mutability::Not }), - &ty::Ref(_, _, hir::Mutability::Not), + &ty::RawPtr(TypeAndMut { ty: ty_b, mutbl: mutbl_b }), + &ty::Ref(_, ty_a, mutbl_a), ) => { - let cause = self.cause(rustc_span::DUMMY_SP, ObligationCauseCode::ExprAssignable); - // We don't ever need two-phase here since we throw out the result of the coercion - let coerce = Coerce::new(self, cause, AllowTwoPhase::No); - - if let Some(steps) = - coerce.autoderef(sp, checked_ty).skip(1).find_map(|(referent_ty, steps)| { - coerce - .unify( - coerce.tcx.mk_ptr(ty::TypeAndMut { - mutbl: hir::Mutability::Not, - ty: referent_ty, - }), - expected, - ) - .ok() - .map(|_| steps) - }) - { - // The pointer type implements `Copy` trait so the suggestion is always valid. - if let Ok(code) = sm.span_to_snippet(sp) { - if code.starts_with('&') { - let derefs = "*".repeat(steps - 1); - let message = "consider dereferencing the reference"; - let suggestion = format!("&{}{}", derefs, code[1..].to_string()); - return Some((sp, message, suggestion)); + if let Some(steps) = self.deref_steps(ty_a, ty_b) { + // Only suggest valid if dereferencing needed. + if steps > 0 { + // The pointer type implements `Copy` trait so the suggestion is always valid. + if let Ok(src) = sm.span_to_snippet(sp) { + let derefs = &"*".repeat(steps); + if let Some((src, applicability)) = match mutbl_b { + hir::Mutability::Mut => { + let new_prefix = "&mut ".to_owned() + derefs; + match mutbl_a { + hir::Mutability::Mut => { + if let Some(s) = + self.replace_prefix(src, "&mut ", new_prefix) + { + Some((s, Applicability::MachineApplicable)) + } else { + None + } + } + hir::Mutability::Not => { + if let Some(s) = + self.replace_prefix(src, "&", new_prefix) + { + Some((s, Applicability::Unspecified)) + } else { + None + } + } + } + } + hir::Mutability::Not => { + let new_prefix = "&".to_owned() + derefs; + match mutbl_a { + hir::Mutability::Mut => { + if let Some(s) = + self.replace_prefix(src, "&mut ", new_prefix) + { + Some((s, Applicability::MachineApplicable)) + } else { + None + } + } + hir::Mutability::Not => { + if let Some(s) = + self.replace_prefix(src, "&", new_prefix) + { + Some((s, Applicability::MachineApplicable)) + } else { + None + } + } + } + } + } { + return Some((sp, "consider dereferencing", src, applicability)); + } } } } @@ -616,7 +672,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { format!("*{}", code) }; - return Some((sp, message, suggestion)); + return Some((sp, message, suggestion, Applicability::MachineApplicable)); } } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c4317451988..6274a11ebd5 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5036,8 +5036,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, found: Ty<'tcx>, ) { - if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) { - err.span_suggestion(sp, msg, suggestion, Applicability::MachineApplicable); + if let Some((sp, msg, suggestion, applicability)) = self.check_ref(expr, found, expected) { + err.span_suggestion(sp, msg, suggestion, applicability); } else if let (ty::FnDef(def_id, ..), true) = (&found.kind, self.suggest_fn_call(err, expr, expected, found)) { diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 1e6b6c430be..a3ee14e85d2 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -497,7 +497,7 @@ impl Drop for WaiterQueue<'_> { let mut queue = (state_and_queue & !STATE_MASK) as *const Waiter; while !queue.is_null() { let next = (*queue).next; - let thread = (*queue).thread.replace(None).unwrap(); + let thread = (*queue).thread.take().unwrap(); (*queue).signaled.store(true, Ordering::Release); // ^- FIXME (maybe): This is another case of issue #55005 // `store()` has a potentially dangling ref to `signaled`. diff --git a/src/test/run-make/wasm-panic-small/foo.rs b/src/test/run-make/wasm-panic-small/foo.rs index fd3dddb18eb..6df52affe39 100644 --- a/src/test/run-make/wasm-panic-small/foo.rs +++ b/src/test/run-make/wasm-panic-small/foo.rs @@ -23,5 +23,5 @@ pub fn foo() { pub fn foo() -> usize { use std::cell::Cell; thread_local!(static A: Cell> = Cell::new(Vec::new())); - A.try_with(|x| x.replace(Vec::new()).len()).unwrap_or(0) + A.try_with(|x| x.take().len()).unwrap_or(0) } diff --git a/src/test/ui/issues/issue-32122-1.stderr b/src/test/ui/issues/issue-32122-1.stderr index 313de275c53..dfbd3223efc 100644 --- a/src/test/ui/issues/issue-32122-1.stderr +++ b/src/test/ui/issues/issue-32122-1.stderr @@ -5,7 +5,7 @@ LL | let _: *const u8 = &a; | --------- ^^ | | | | | expected `u8`, found struct `Foo` - | | help: consider dereferencing the reference: `&*a` + | | help: consider dereferencing: `&*a` | expected due to this | = note: expected raw pointer `*const u8` diff --git a/src/test/ui/issues/issue-32122-2.stderr b/src/test/ui/issues/issue-32122-2.stderr index 959a49507e4..2e199e2a19f 100644 --- a/src/test/ui/issues/issue-32122-2.stderr +++ b/src/test/ui/issues/issue-32122-2.stderr @@ -5,7 +5,7 @@ LL | let _: *const u8 = &a; | --------- ^^ | | | | | expected `u8`, found struct `Emm` - | | help: consider dereferencing the reference: `&***a` + | | help: consider dereferencing: `&***a` | expected due to this | = note: expected raw pointer `*const u8` diff --git a/src/test/ui/issues/issue-71676-1.fixed b/src/test/ui/issues/issue-71676-1.fixed new file mode 100644 index 00000000000..cbc0e8c061b --- /dev/null +++ b/src/test/ui/issues/issue-71676-1.fixed @@ -0,0 +1,53 @@ +// run-rustfix +use std::ops::Deref; +use std::ops::DerefMut; +struct Bar(u8); +struct Foo(Bar); +struct Emm(Foo); +impl Deref for Bar{ + type Target = u8; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl Deref for Foo { + type Target = Bar; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl Deref for Emm { + type Target = Foo; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl DerefMut for Bar{ + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +impl DerefMut for Foo { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +impl DerefMut for Emm { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +fn main() { + // Suggest dereference with arbitrary mutability + let a = Emm(Foo(Bar(0))); + let _: *const u8 = &***a; //~ ERROR mismatched types + + let mut a = Emm(Foo(Bar(0))); + let _: *mut u8 = &mut ***a; //~ ERROR mismatched types + + let a = Emm(Foo(Bar(0))); + let _: *const u8 = &***a; //~ ERROR mismatched types + + let mut a = Emm(Foo(Bar(0))); + let _: *mut u8 = &mut ***a; //~ ERROR mismatched types +} diff --git a/src/test/ui/issues/issue-71676-1.rs b/src/test/ui/issues/issue-71676-1.rs new file mode 100644 index 00000000000..6e87c7174c6 --- /dev/null +++ b/src/test/ui/issues/issue-71676-1.rs @@ -0,0 +1,53 @@ +// run-rustfix +use std::ops::Deref; +use std::ops::DerefMut; +struct Bar(u8); +struct Foo(Bar); +struct Emm(Foo); +impl Deref for Bar{ + type Target = u8; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl Deref for Foo { + type Target = Bar; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl Deref for Emm { + type Target = Foo; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl DerefMut for Bar{ + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +impl DerefMut for Foo { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +impl DerefMut for Emm { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +fn main() { + // Suggest dereference with arbitrary mutability + let a = Emm(Foo(Bar(0))); + let _: *const u8 = &a; //~ ERROR mismatched types + + let mut a = Emm(Foo(Bar(0))); + let _: *mut u8 = &a; //~ ERROR mismatched types + + let a = Emm(Foo(Bar(0))); + let _: *const u8 = &mut a; //~ ERROR mismatched types + + let mut a = Emm(Foo(Bar(0))); + let _: *mut u8 = &mut a; //~ ERROR mismatched types +} diff --git a/src/test/ui/issues/issue-71676-1.stderr b/src/test/ui/issues/issue-71676-1.stderr new file mode 100644 index 00000000000..bbabc2202dc --- /dev/null +++ b/src/test/ui/issues/issue-71676-1.stderr @@ -0,0 +1,55 @@ +error[E0308]: mismatched types + --> $DIR/issue-71676-1.rs:43:24 + | +LL | let _: *const u8 = &a; + | --------- ^^ + | | | + | | expected `u8`, found struct `Emm` + | | help: consider dereferencing: `&***a` + | expected due to this + | + = note: expected raw pointer `*const u8` + found reference `&Emm` + +error[E0308]: mismatched types + --> $DIR/issue-71676-1.rs:46:22 + | +LL | let _: *mut u8 = &a; + | ------- ^^ + | | | + | | types differ in mutability + | | help: consider dereferencing: `&mut ***a` + | expected due to this + | + = note: expected raw pointer `*mut u8` + found reference `&Emm` + +error[E0308]: mismatched types + --> $DIR/issue-71676-1.rs:49:24 + | +LL | let _: *const u8 = &mut a; + | --------- ^^^^^^ + | | | + | | expected `u8`, found struct `Emm` + | | help: consider dereferencing: `&***a` + | expected due to this + | + = note: expected raw pointer `*const u8` + found mutable reference `&mut Emm` + +error[E0308]: mismatched types + --> $DIR/issue-71676-1.rs:52:22 + | +LL | let _: *mut u8 = &mut a; + | ------- ^^^^^^ + | | | + | | expected `u8`, found struct `Emm` + | | help: consider dereferencing: `&mut ***a` + | expected due to this + | + = note: expected raw pointer `*mut u8` + found mutable reference `&mut Emm` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issues/issue-71676-2.rs b/src/test/ui/issues/issue-71676-2.rs new file mode 100644 index 00000000000..f3183899dc5 --- /dev/null +++ b/src/test/ui/issues/issue-71676-2.rs @@ -0,0 +1,42 @@ +use std::ops::Deref; +use std::ops::DerefMut; +struct Bar(u8); +struct Foo(Bar); +struct Emm(Foo); +impl Deref for Bar{ + type Target = u8; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl Deref for Foo { + type Target = Bar; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl Deref for Emm { + type Target = Foo; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl DerefMut for Bar{ + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +impl DerefMut for Foo { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +impl DerefMut for Emm { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +fn main() { + let a = Emm(Foo(Bar(0))); + let _: *mut u8 = &a; //~ ERROR mismatched types +} diff --git a/src/test/ui/issues/issue-71676-2.stderr b/src/test/ui/issues/issue-71676-2.stderr new file mode 100644 index 00000000000..ebdd345809a --- /dev/null +++ b/src/test/ui/issues/issue-71676-2.stderr @@ -0,0 +1,16 @@ +error[E0308]: mismatched types + --> $DIR/issue-71676-2.rs:41:22 + | +LL | let _: *mut u8 = &a; + | ------- ^^ + | | | + | | types differ in mutability + | | help: consider dereferencing: `&mut ***a` + | expected due to this + | + = note: expected raw pointer `*mut u8` + found reference `&Emm` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr index ce9b02b6d82..0c328a2594a 100644 --- a/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr +++ b/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr @@ -1,146 +1,152 @@ -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:22:13 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:17:20 + | +LL | const N: i32 = T::N << 42; + | ^^^^^^^^^^ attempt to shift left with overflow + | +note: the lint level is defined here + --> $DIR/lint-exceeding-bitshifts.rs:8:9 + | +LL | #![warn(arithmetic_overflow, const_err)] + | ^^^^^^^^^^^^^^^^^^^ + +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:21:13 | LL | let _ = x << 42; | ^^^^^^^ attempt to shift left with overflow - | -note: the lint level is defined here - --> $DIR/lint-exceeding-bitshifts.rs:9:9 - | -LL | #![deny(arithmetic_overflow, const_err)] - | ^^^^^^^^^^^^^^^^^^^ -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:27:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:26:15 | LL | let n = 1u8 << 8; | ^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:29:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:28:15 | LL | let n = 1u16 << 16; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:31:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:30:15 | LL | let n = 1u32 << 32; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:33:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:32:15 | LL | let n = 1u64 << 64; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:35:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:34:15 | LL | let n = 1i8 << 8; | ^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:37:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:36:15 | LL | let n = 1i16 << 16; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:39:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:38:15 | LL | let n = 1i32 << 32; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:41:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:40:15 | LL | let n = 1i64 << 64; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:44:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:43:15 | LL | let n = 1u8 >> 8; | ^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:46:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:45:15 | LL | let n = 1u16 >> 16; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:48:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:47:15 | LL | let n = 1u32 >> 32; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:50:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:49:15 | LL | let n = 1u64 >> 64; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:52:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:51:15 | LL | let n = 1i8 >> 8; | ^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:54:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:53:15 | LL | let n = 1i16 >> 16; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:56:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:55:15 | LL | let n = 1i32 >> 32; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:58:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:57:15 | LL | let n = 1i64 >> 64; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:62:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:61:15 | LL | let n = n << 8; | ^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:64:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:63:15 | LL | let n = 1u8 << -8; | ^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:69:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:68:15 | LL | let n = 1u8 << (4+4); | ^^^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:71:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:70:15 | LL | let n = 1i64 >> [64][0]; | ^^^^^^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:77:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:76:15 | LL | let n = 1_isize << BITS; | ^^^^^^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:78:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:77:15 | LL | let n = 1_usize << BITS; | ^^^^^^^^^^^^^^^ attempt to shift left with overflow -error: aborting due to 23 previous errors +warning: 24 warnings emitted diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr index ce9b02b6d82..0c328a2594a 100644 --- a/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr +++ b/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr @@ -1,146 +1,152 @@ -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:22:13 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:17:20 + | +LL | const N: i32 = T::N << 42; + | ^^^^^^^^^^ attempt to shift left with overflow + | +note: the lint level is defined here + --> $DIR/lint-exceeding-bitshifts.rs:8:9 + | +LL | #![warn(arithmetic_overflow, const_err)] + | ^^^^^^^^^^^^^^^^^^^ + +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:21:13 | LL | let _ = x << 42; | ^^^^^^^ attempt to shift left with overflow - | -note: the lint level is defined here - --> $DIR/lint-exceeding-bitshifts.rs:9:9 - | -LL | #![deny(arithmetic_overflow, const_err)] - | ^^^^^^^^^^^^^^^^^^^ -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:27:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:26:15 | LL | let n = 1u8 << 8; | ^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:29:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:28:15 | LL | let n = 1u16 << 16; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:31:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:30:15 | LL | let n = 1u32 << 32; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:33:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:32:15 | LL | let n = 1u64 << 64; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:35:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:34:15 | LL | let n = 1i8 << 8; | ^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:37:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:36:15 | LL | let n = 1i16 << 16; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:39:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:38:15 | LL | let n = 1i32 << 32; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:41:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:40:15 | LL | let n = 1i64 << 64; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:44:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:43:15 | LL | let n = 1u8 >> 8; | ^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:46:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:45:15 | LL | let n = 1u16 >> 16; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:48:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:47:15 | LL | let n = 1u32 >> 32; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:50:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:49:15 | LL | let n = 1u64 >> 64; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:52:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:51:15 | LL | let n = 1i8 >> 8; | ^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:54:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:53:15 | LL | let n = 1i16 >> 16; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:56:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:55:15 | LL | let n = 1i32 >> 32; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:58:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:57:15 | LL | let n = 1i64 >> 64; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:62:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:61:15 | LL | let n = n << 8; | ^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:64:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:63:15 | LL | let n = 1u8 << -8; | ^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:69:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:68:15 | LL | let n = 1u8 << (4+4); | ^^^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:71:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:70:15 | LL | let n = 1i64 >> [64][0]; | ^^^^^^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:77:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:76:15 | LL | let n = 1_isize << BITS; | ^^^^^^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:78:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:77:15 | LL | let n = 1_usize << BITS; | ^^^^^^^^^^^^^^^ attempt to shift left with overflow -error: aborting due to 23 previous errors +warning: 24 warnings emitted diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr index ce9b02b6d82..0c328a2594a 100644 --- a/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr +++ b/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr @@ -1,146 +1,152 @@ -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:22:13 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:17:20 + | +LL | const N: i32 = T::N << 42; + | ^^^^^^^^^^ attempt to shift left with overflow + | +note: the lint level is defined here + --> $DIR/lint-exceeding-bitshifts.rs:8:9 + | +LL | #![warn(arithmetic_overflow, const_err)] + | ^^^^^^^^^^^^^^^^^^^ + +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:21:13 | LL | let _ = x << 42; | ^^^^^^^ attempt to shift left with overflow - | -note: the lint level is defined here - --> $DIR/lint-exceeding-bitshifts.rs:9:9 - | -LL | #![deny(arithmetic_overflow, const_err)] - | ^^^^^^^^^^^^^^^^^^^ -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:27:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:26:15 | LL | let n = 1u8 << 8; | ^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:29:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:28:15 | LL | let n = 1u16 << 16; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:31:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:30:15 | LL | let n = 1u32 << 32; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:33:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:32:15 | LL | let n = 1u64 << 64; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:35:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:34:15 | LL | let n = 1i8 << 8; | ^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:37:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:36:15 | LL | let n = 1i16 << 16; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:39:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:38:15 | LL | let n = 1i32 << 32; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:41:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:40:15 | LL | let n = 1i64 << 64; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:44:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:43:15 | LL | let n = 1u8 >> 8; | ^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:46:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:45:15 | LL | let n = 1u16 >> 16; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:48:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:47:15 | LL | let n = 1u32 >> 32; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:50:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:49:15 | LL | let n = 1u64 >> 64; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:52:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:51:15 | LL | let n = 1i8 >> 8; | ^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:54:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:53:15 | LL | let n = 1i16 >> 16; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:56:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:55:15 | LL | let n = 1i32 >> 32; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:58:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:57:15 | LL | let n = 1i64 >> 64; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:62:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:61:15 | LL | let n = n << 8; | ^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:64:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:63:15 | LL | let n = 1u8 << -8; | ^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:69:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:68:15 | LL | let n = 1u8 << (4+4); | ^^^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:71:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:70:15 | LL | let n = 1i64 >> [64][0]; | ^^^^^^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:77:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:76:15 | LL | let n = 1_isize << BITS; | ^^^^^^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:78:15 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:77:15 | LL | let n = 1_usize << BITS; | ^^^^^^^^^^^^^^^ attempt to shift left with overflow -error: aborting due to 23 previous errors +warning: 24 warnings emitted diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.rs b/src/test/ui/lint/lint-exceeding-bitshifts.rs index 7deee5320a8..565bef49c9f 100644 --- a/src/test/ui/lint/lint-exceeding-bitshifts.rs +++ b/src/test/ui/lint/lint-exceeding-bitshifts.rs @@ -2,11 +2,10 @@ //[noopt]compile-flags: -C opt-level=0 //[opt]compile-flags: -O //[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O - -// build-fail +// build-pass #![crate_type="lib"] -#![deny(arithmetic_overflow, const_err)] +#![warn(arithmetic_overflow, const_err)] #![allow(unused_variables)] #![allow(dead_code)] @@ -15,65 +14,65 @@ pub trait Foo { } impl Foo for Vec { - const N: i32 = T::N << 42; // FIXME this should warn + const N: i32 = T::N << 42; //~ WARN: arithmetic operation will overflow } pub fn foo(x: i32) { - let _ = x << 42; //~ ERROR: arithmetic operation will overflow + let _ = x << 42; //~ WARN: arithmetic operation will overflow } pub fn main() { let n = 1u8 << 7; - let n = 1u8 << 8; //~ ERROR: arithmetic operation will overflow + let n = 1u8 << 8; //~ WARN: arithmetic operation will overflow let n = 1u16 << 15; - let n = 1u16 << 16; //~ ERROR: arithmetic operation will overflow + let n = 1u16 << 16; //~ WARN: arithmetic operation will overflow let n = 1u32 << 31; - let n = 1u32 << 32; //~ ERROR: arithmetic operation will overflow + let n = 1u32 << 32; //~ WARN: arithmetic operation will overflow let n = 1u64 << 63; - let n = 1u64 << 64; //~ ERROR: arithmetic operation will overflow + let n = 1u64 << 64; //~ WARN: arithmetic operation will overflow let n = 1i8 << 7; - let n = 1i8 << 8; //~ ERROR: arithmetic operation will overflow + let n = 1i8 << 8; //~ WARN: arithmetic operation will overflow let n = 1i16 << 15; - let n = 1i16 << 16; //~ ERROR: arithmetic operation will overflow + let n = 1i16 << 16; //~ WARN: arithmetic operation will overflow let n = 1i32 << 31; - let n = 1i32 << 32; //~ ERROR: arithmetic operation will overflow + let n = 1i32 << 32; //~ WARN: arithmetic operation will overflow let n = 1i64 << 63; - let n = 1i64 << 64; //~ ERROR: arithmetic operation will overflow + let n = 1i64 << 64; //~ WARN: arithmetic operation will overflow let n = 1u8 >> 7; - let n = 1u8 >> 8; //~ ERROR: arithmetic operation will overflow + let n = 1u8 >> 8; //~ WARN: arithmetic operation will overflow let n = 1u16 >> 15; - let n = 1u16 >> 16; //~ ERROR: arithmetic operation will overflow + let n = 1u16 >> 16; //~ WARN: arithmetic operation will overflow let n = 1u32 >> 31; - let n = 1u32 >> 32; //~ ERROR: arithmetic operation will overflow + let n = 1u32 >> 32; //~ WARN: arithmetic operation will overflow let n = 1u64 >> 63; - let n = 1u64 >> 64; //~ ERROR: arithmetic operation will overflow + let n = 1u64 >> 64; //~ WARN: arithmetic operation will overflow let n = 1i8 >> 7; - let n = 1i8 >> 8; //~ ERROR: arithmetic operation will overflow + let n = 1i8 >> 8; //~ WARN: arithmetic operation will overflow let n = 1i16 >> 15; - let n = 1i16 >> 16; //~ ERROR: arithmetic operation will overflow + let n = 1i16 >> 16; //~ WARN: arithmetic operation will overflow let n = 1i32 >> 31; - let n = 1i32 >> 32; //~ ERROR: arithmetic operation will overflow + let n = 1i32 >> 32; //~ WARN: arithmetic operation will overflow let n = 1i64 >> 63; - let n = 1i64 >> 64; //~ ERROR: arithmetic operation will overflow + let n = 1i64 >> 64; //~ WARN: arithmetic operation will overflow let n = 1u8; let n = n << 7; - let n = n << 8; //~ ERROR: arithmetic operation will overflow + let n = n << 8; //~ WARN: arithmetic operation will overflow - let n = 1u8 << -8; //~ ERROR: arithmetic operation will overflow + let n = 1u8 << -8; //~ WARN: arithmetic operation will overflow let n = 1i8<<(1isize+-1); let n = 1u8 << (4+3); - let n = 1u8 << (4+4); //~ ERROR: arithmetic operation will overflow + let n = 1u8 << (4+4); //~ WARN: arithmetic operation will overflow let n = 1i64 >> [63][0]; - let n = 1i64 >> [64][0]; //~ ERROR: arithmetic operation will overflow + let n = 1i64 >> [64][0]; //~ WARN: arithmetic operation will overflow #[cfg(target_pointer_width = "32")] const BITS: usize = 32; #[cfg(target_pointer_width = "64")] const BITS: usize = 64; - let n = 1_isize << BITS; //~ ERROR: arithmetic operation will overflow - let n = 1_usize << BITS; //~ ERROR: arithmetic operation will overflow + let n = 1_isize << BITS; //~ WARN: arithmetic operation will overflow + let n = 1_usize << BITS; //~ WARN: arithmetic operation will overflow } diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr index d0ca1705037..3c5da3f1440 100644 --- a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr +++ b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr @@ -108,4 +108,5 @@ LL | fn deprecated_without_unstable_or_stable() { } error: aborting due to 18 previous errors -For more information about this error, try `rustc --explain E0541`. +Some errors have detailed explanations: E0539, E0541. +For more information about an error, try `rustc --explain E0539`. diff --git a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs index 499ac461e59..a5b85646581 100644 --- a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs +++ b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs @@ -7,7 +7,7 @@ struct MyType<'a>(Cell>>, PhantomPinned); impl<'a> Clone for &'a mut MyType<'a> { //~^ ERROR E0751 fn clone(&self) -> &'a mut MyType<'a> { - self.0.replace(None).unwrap() + self.0.take().unwrap() } } diff --git a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.rs b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.rs index 245be800780..606cc65a84b 100644 --- a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.rs +++ b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.rs @@ -12,7 +12,7 @@ struct MyType<'a>(Cell>>, PhantomPinned); impl<'a> DerefMut for &'a MyType<'a> { //~^ ERROR E0751 fn deref_mut(&mut self) -> &mut MyType<'a> { - self.0.replace(None).unwrap() + self.0.take().unwrap() } }