Auto merge of #71853 - Dylan-DPC:rollup-4qi6ry9, r=Dylan-DPC

Rollup of 4 pull requests

Successful merges:

 - #71398 (Add `RefCell::take`)
 - #71663 (Fix exceeding bitshifts not emitting for assoc. consts (properly this time, I swear!))
 - #71726 (Suggest deref when coercing `ty::Ref` to `ty::RawPtr` with arbitrary mutability)
 - #71808 (Add long error explanation for E0539)

Failed merges:

r? @ghost
This commit is contained in:
bors 2020-05-03 16:38:41 +00:00
commit ea733c3a59
24 changed files with 683 additions and 275 deletions

View File

@ -1023,6 +1023,31 @@ impl<T: ?Sized> RefCell<T> {
}
}
impl<T: Default> RefCell<T> {
/// 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<T: ?Sized> Send for RefCell<T> where T: Send {}

View File

@ -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'

View File

@ -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() {}
```

View File

@ -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),
}
}

View File

@ -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)?;

View File

@ -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<usize> {
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").

View File

@ -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<A, B, C>(&self, s: A, old: B, new: C) -> Option<String>
where
A: AsRef<str>,
B: AsRef<str>,
C: AsRef<str>,
{
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));
}
}
}

View File

@ -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))
{

View File

@ -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`.

View File

@ -23,5 +23,5 @@ pub fn foo() {
pub fn foo() -> usize {
use std::cell::Cell;
thread_local!(static A: Cell<Vec<u32>> = 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)
}

View File

@ -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`

View File

@ -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`

View File

@ -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
}

View File

@ -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
}

View File

@ -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`.

View File

@ -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
}

View File

@ -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`.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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<T: Foo> Foo for Vec<T> {
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
}

View File

@ -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`.

View File

@ -7,7 +7,7 @@ struct MyType<'a>(Cell<Option<&'a mut MyType<'a>>>, 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()
}
}

View File

@ -12,7 +12,7 @@ struct MyType<'a>(Cell<Option<&'a mut MyType<'a>>>, 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()
}
}