mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 23:12:02 +00:00
Rollup merge of #112529 - jieyouxu:block-expr-unused-must-use, r=oli-obk
Extend `unused_must_use` to cover block exprs Given code like ```rust #[must_use] fn foo() -> i32 { 42 } fn warns() { { foo(); } } fn does_not_warn() { { foo() }; } fn main() { warns(); does_not_warn(); } ``` ### Before This PR ``` warning: unused return value of `foo` that must be used --> test.rs:8:9 | 8 | foo(); | ^^^^^ | = note: `#[warn(unused_must_use)]` on by default help: use `let _ = ...` to ignore the resulting value | 8 | let _ = foo(); | +++++++ warning: 1 warning emitted ``` ### After This PR ``` warning: unused return value of `foo` that must be used --> test.rs:8:9 | 8 | foo(); | ^^^^^ | = note: `#[warn(unused_must_use)]` on by default help: use `let _ = ...` to ignore the resulting value | 8 | let _ = foo(); | +++++++ warning: unused return value of `foo` that must be used --> test.rs:14:9 | 14 | foo() | ^^^^^ | help: use `let _ = ...` to ignore the resulting value | 14 | let _ = foo(); | +++++++ + warning: 2 warnings emitted ``` Fixes #104253.
This commit is contained in:
commit
d233522418
@ -67,7 +67,7 @@ struct ArenaChunk<T = u8> {
|
||||
|
||||
unsafe impl<#[may_dangle] T> Drop for ArenaChunk<T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { Box::from_raw(self.storage.as_mut()) };
|
||||
unsafe { drop(Box::from_raw(self.storage.as_mut())) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1555,8 +1555,29 @@ pub struct UnusedOp<'a> {
|
||||
pub op: &'a str,
|
||||
#[label]
|
||||
pub label: Span,
|
||||
#[suggestion(style = "verbose", code = "let _ = ", applicability = "maybe-incorrect")]
|
||||
pub suggestion: Span,
|
||||
#[subdiagnostic]
|
||||
pub suggestion: UnusedOpSuggestion,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum UnusedOpSuggestion {
|
||||
#[suggestion(
|
||||
lint_suggestion,
|
||||
style = "verbose",
|
||||
code = "let _ = ",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
NormalExpr {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
|
||||
BlockTailExpr {
|
||||
#[suggestion_part(code = "let _ = ")]
|
||||
before_span: Span,
|
||||
#[suggestion_part(code = ";")]
|
||||
after_span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
@ -1599,15 +1620,25 @@ pub struct UnusedDef<'a, 'b> {
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(
|
||||
lint_suggestion,
|
||||
style = "verbose",
|
||||
code = "let _ = ",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
pub struct UnusedDefSuggestion {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
||||
pub enum UnusedDefSuggestion {
|
||||
#[suggestion(
|
||||
lint_suggestion,
|
||||
style = "verbose",
|
||||
code = "let _ = ",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
NormalExpr {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
|
||||
BlockTailExpr {
|
||||
#[suggestion_part(code = "let _ = ")]
|
||||
before_span: Span,
|
||||
#[suggestion_part(code = ";")]
|
||||
after_span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
// Needed because of def_path_str
|
||||
|
@ -1,7 +1,8 @@
|
||||
use crate::lints::{
|
||||
PathStatementDrop, PathStatementDropSub, PathStatementNoEffect, UnusedAllocationDiag,
|
||||
UnusedAllocationMutDiag, UnusedClosure, UnusedDef, UnusedDefSuggestion, UnusedDelim,
|
||||
UnusedDelimSuggestion, UnusedGenerator, UnusedImportBracesDiag, UnusedOp, UnusedResult,
|
||||
UnusedDelimSuggestion, UnusedGenerator, UnusedImportBracesDiag, UnusedOp, UnusedOpSuggestion,
|
||||
UnusedResult,
|
||||
};
|
||||
use crate::Lint;
|
||||
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||
@ -93,7 +94,15 @@ declare_lint_pass!(UnusedResults => [UNUSED_MUST_USE, UNUSED_RESULTS]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) {
|
||||
let hir::StmtKind::Semi(expr) = s.kind else { return; };
|
||||
let hir::StmtKind::Semi(mut expr) = s.kind else { return; };
|
||||
|
||||
let mut expr_is_from_block = false;
|
||||
while let hir::ExprKind::Block(blk, ..) = expr.kind
|
||||
&& let hir::Block { expr: Some(e), .. } = blk
|
||||
{
|
||||
expr = e;
|
||||
expr_is_from_block = true;
|
||||
}
|
||||
|
||||
if let hir::ExprKind::Ret(..) = expr.kind {
|
||||
return;
|
||||
@ -113,6 +122,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
expr.span,
|
||||
"output of future returned by ",
|
||||
"",
|
||||
expr_is_from_block,
|
||||
)
|
||||
{
|
||||
// We have a bare `foo().await;` on an opaque type from an async function that was
|
||||
@ -125,13 +135,13 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
let must_use_result = is_ty_must_use(cx, ty, &expr, expr.span);
|
||||
let type_lint_emitted_or_suppressed = match must_use_result {
|
||||
Some(path) => {
|
||||
emit_must_use_untranslated(cx, &path, "", "", 1, false);
|
||||
emit_must_use_untranslated(cx, &path, "", "", 1, false, expr_is_from_block);
|
||||
true
|
||||
}
|
||||
None => false,
|
||||
};
|
||||
|
||||
let fn_warned = check_fn_must_use(cx, expr);
|
||||
let fn_warned = check_fn_must_use(cx, expr, expr_is_from_block);
|
||||
|
||||
if !fn_warned && type_lint_emitted_or_suppressed {
|
||||
// We don't warn about unused unit or uninhabited types.
|
||||
@ -176,7 +186,14 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
UnusedOp {
|
||||
op: must_use_op,
|
||||
label: expr.span,
|
||||
suggestion: expr.span.shrink_to_lo(),
|
||||
suggestion: if expr_is_from_block {
|
||||
UnusedOpSuggestion::BlockTailExpr {
|
||||
before_span: expr.span.shrink_to_lo(),
|
||||
after_span: expr.span.shrink_to_hi(),
|
||||
}
|
||||
} else {
|
||||
UnusedOpSuggestion::NormalExpr { span: expr.span.shrink_to_lo() }
|
||||
},
|
||||
},
|
||||
);
|
||||
op_warned = true;
|
||||
@ -186,7 +203,11 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
cx.emit_spanned_lint(UNUSED_RESULTS, s.span, UnusedResult { ty });
|
||||
}
|
||||
|
||||
fn check_fn_must_use(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
|
||||
fn check_fn_must_use(
|
||||
cx: &LateContext<'_>,
|
||||
expr: &hir::Expr<'_>,
|
||||
expr_is_from_block: bool,
|
||||
) -> bool {
|
||||
let maybe_def_id = match expr.kind {
|
||||
hir::ExprKind::Call(ref callee, _) => {
|
||||
match callee.kind {
|
||||
@ -207,7 +228,14 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
_ => None,
|
||||
};
|
||||
if let Some(def_id) = maybe_def_id {
|
||||
check_must_use_def(cx, def_id, expr.span, "return value of ", "")
|
||||
check_must_use_def(
|
||||
cx,
|
||||
def_id,
|
||||
expr.span,
|
||||
"return value of ",
|
||||
"",
|
||||
expr_is_from_block,
|
||||
)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@ -350,6 +378,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
span: Span,
|
||||
descr_pre_path: &str,
|
||||
descr_post_path: &str,
|
||||
expr_is_from_block: bool,
|
||||
) -> bool {
|
||||
is_def_must_use(cx, def_id, span)
|
||||
.map(|must_use_path| {
|
||||
@ -360,6 +389,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
descr_post_path,
|
||||
1,
|
||||
false,
|
||||
expr_is_from_block,
|
||||
)
|
||||
})
|
||||
.is_some()
|
||||
@ -373,6 +403,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
descr_post: &str,
|
||||
plural_len: usize,
|
||||
is_inner: bool,
|
||||
expr_is_from_block: bool,
|
||||
) {
|
||||
let plural_suffix = pluralize!(plural_len);
|
||||
|
||||
@ -380,21 +411,51 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
MustUsePath::Suppressed => {}
|
||||
MustUsePath::Boxed(path) => {
|
||||
let descr_pre = &format!("{}boxed ", descr_pre);
|
||||
emit_must_use_untranslated(cx, path, descr_pre, descr_post, plural_len, true);
|
||||
emit_must_use_untranslated(
|
||||
cx,
|
||||
path,
|
||||
descr_pre,
|
||||
descr_post,
|
||||
plural_len,
|
||||
true,
|
||||
expr_is_from_block,
|
||||
);
|
||||
}
|
||||
MustUsePath::Opaque(path) => {
|
||||
let descr_pre = &format!("{}implementer{} of ", descr_pre, plural_suffix);
|
||||
emit_must_use_untranslated(cx, path, descr_pre, descr_post, plural_len, true);
|
||||
emit_must_use_untranslated(
|
||||
cx,
|
||||
path,
|
||||
descr_pre,
|
||||
descr_post,
|
||||
plural_len,
|
||||
true,
|
||||
expr_is_from_block,
|
||||
);
|
||||
}
|
||||
MustUsePath::TraitObject(path) => {
|
||||
let descr_post = &format!(" trait object{}{}", plural_suffix, descr_post);
|
||||
emit_must_use_untranslated(cx, path, descr_pre, descr_post, plural_len, true);
|
||||
emit_must_use_untranslated(
|
||||
cx,
|
||||
path,
|
||||
descr_pre,
|
||||
descr_post,
|
||||
plural_len,
|
||||
true,
|
||||
expr_is_from_block,
|
||||
);
|
||||
}
|
||||
MustUsePath::TupleElement(elems) => {
|
||||
for (index, path) in elems {
|
||||
let descr_post = &format!(" in tuple element {}", index);
|
||||
emit_must_use_untranslated(
|
||||
cx, path, descr_pre, descr_post, plural_len, true,
|
||||
cx,
|
||||
path,
|
||||
descr_pre,
|
||||
descr_post,
|
||||
plural_len,
|
||||
true,
|
||||
expr_is_from_block,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -407,6 +468,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
descr_post,
|
||||
plural_len.saturating_add(usize::try_from(*len).unwrap_or(usize::MAX)),
|
||||
true,
|
||||
expr_is_from_block,
|
||||
);
|
||||
}
|
||||
MustUsePath::Closure(span) => {
|
||||
@ -433,8 +495,14 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
cx,
|
||||
def_id: *def_id,
|
||||
note: *reason,
|
||||
suggestion: (!is_inner)
|
||||
.then_some(UnusedDefSuggestion { span: span.shrink_to_lo() }),
|
||||
suggestion: (!is_inner).then_some(if expr_is_from_block {
|
||||
UnusedDefSuggestion::BlockTailExpr {
|
||||
before_span: span.shrink_to_lo(),
|
||||
after_span: span.shrink_to_hi(),
|
||||
}
|
||||
} else {
|
||||
UnusedDefSuggestion::NormalExpr { span: span.shrink_to_lo() }
|
||||
}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -308,7 +308,7 @@ mod prim_never {}
|
||||
///
|
||||
/// ```no_run
|
||||
/// // Undefined behaviour
|
||||
/// unsafe { char::from_u32_unchecked(0x110000) };
|
||||
/// let _ = unsafe { char::from_u32_unchecked(0x110000) };
|
||||
/// ```
|
||||
///
|
||||
/// USVs are also the exact set of values that may be encoded in UTF-8. Because
|
||||
|
@ -1001,7 +1001,7 @@ fn nonnull_tagged_pointer_with_provenance() {
|
||||
assert_eq!(p.tag(), 3);
|
||||
assert_eq!(unsafe { *p.pointer().as_ptr() }, 10);
|
||||
|
||||
unsafe { Box::from_raw(p.pointer().as_ptr()) };
|
||||
unsafe { drop(Box::from_raw(p.pointer().as_ptr())) };
|
||||
|
||||
/// A non-null pointer type which carries several bits of metadata and maintains provenance.
|
||||
#[repr(transparent)]
|
||||
|
@ -308,7 +308,7 @@ mod prim_never {}
|
||||
///
|
||||
/// ```no_run
|
||||
/// // Undefined behaviour
|
||||
/// unsafe { char::from_u32_unchecked(0x110000) };
|
||||
/// let _ = unsafe { char::from_u32_unchecked(0x110000) };
|
||||
/// ```
|
||||
///
|
||||
/// USVs are also the exact set of values that may be encoded in UTF-8. Because
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#![warn(clippy::transmute_ptr_to_ref)]
|
||||
#![allow(clippy::match_single_binding)]
|
||||
#![allow(unused_must_use)]
|
||||
|
||||
unsafe fn _ptr_to_ref<T, U>(p: *const T, m: *mut T, o: *const U, om: *mut U) {
|
||||
let _: &T = &*p;
|
||||
@ -38,7 +39,7 @@ fn _issue1231() {
|
||||
|
||||
type Bar<'a> = &'a u8;
|
||||
let raw = 42 as *const i32;
|
||||
unsafe { &*(raw as *const u8) };
|
||||
let _ = unsafe { &*(raw as *const u8) };
|
||||
}
|
||||
|
||||
unsafe fn _issue8924<'a, 'b, 'c>(x: *const &'a u32, y: *const &'b u32) -> &'c &'b u32 {
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#![warn(clippy::transmute_ptr_to_ref)]
|
||||
#![allow(clippy::match_single_binding)]
|
||||
#![allow(unused_must_use)]
|
||||
|
||||
unsafe fn _ptr_to_ref<T, U>(p: *const T, m: *mut T, o: *const U, om: *mut U) {
|
||||
let _: &T = std::mem::transmute(p);
|
||||
@ -38,7 +39,7 @@ fn _issue1231() {
|
||||
|
||||
type Bar<'a> = &'a u8;
|
||||
let raw = 42 as *const i32;
|
||||
unsafe { std::mem::transmute::<_, Bar>(raw) };
|
||||
let _ = unsafe { std::mem::transmute::<_, Bar>(raw) };
|
||||
}
|
||||
|
||||
unsafe fn _issue8924<'a, 'b, 'c>(x: *const &'a u32, y: *const &'b u32) -> &'c &'b u32 {
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: transmute from a pointer type (`*const T`) to a reference type (`&T`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:7:17
|
||||
--> $DIR/transmute_ptr_to_ref.rs:8:17
|
||||
|
|
||||
LL | let _: &T = std::mem::transmute(p);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*p`
|
||||
@ -7,127 +7,127 @@ LL | let _: &T = std::mem::transmute(p);
|
||||
= note: `-D clippy::transmute-ptr-to-ref` implied by `-D warnings`
|
||||
|
||||
error: transmute from a pointer type (`*mut T`) to a reference type (`&mut T`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:10:21
|
||||
--> $DIR/transmute_ptr_to_ref.rs:11:21
|
||||
|
|
||||
LL | let _: &mut T = std::mem::transmute(m);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *m`
|
||||
|
||||
error: transmute from a pointer type (`*mut T`) to a reference type (`&T`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:13:17
|
||||
--> $DIR/transmute_ptr_to_ref.rs:14:17
|
||||
|
|
||||
LL | let _: &T = std::mem::transmute(m);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*m`
|
||||
|
||||
error: transmute from a pointer type (`*mut T`) to a reference type (`&mut T`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:16:21
|
||||
--> $DIR/transmute_ptr_to_ref.rs:17:21
|
||||
|
|
||||
LL | let _: &mut T = std::mem::transmute(p as *mut T);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(p as *mut T)`
|
||||
|
||||
error: transmute from a pointer type (`*const U`) to a reference type (`&T`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:19:17
|
||||
--> $DIR/transmute_ptr_to_ref.rs:20:17
|
||||
|
|
||||
LL | let _: &T = std::mem::transmute(o);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(o as *const T)`
|
||||
|
||||
error: transmute from a pointer type (`*mut U`) to a reference type (`&mut T`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:22:21
|
||||
--> $DIR/transmute_ptr_to_ref.rs:23:21
|
||||
|
|
||||
LL | let _: &mut T = std::mem::transmute(om);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(om as *mut T)`
|
||||
|
||||
error: transmute from a pointer type (`*mut U`) to a reference type (`&T`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:25:17
|
||||
--> $DIR/transmute_ptr_to_ref.rs:26:17
|
||||
|
|
||||
LL | let _: &T = std::mem::transmute(om);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(om as *const T)`
|
||||
|
||||
error: transmute from a pointer type (`*const i32`) to a reference type (`&_issue1231::Foo<'_, u8>`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:35:32
|
||||
--> $DIR/transmute_ptr_to_ref.rs:36:32
|
||||
|
|
||||
LL | let _: &Foo<u8> = unsafe { std::mem::transmute::<_, &Foo<_>>(raw) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*raw.cast::<Foo<_>>()`
|
||||
|
||||
error: transmute from a pointer type (`*const i32`) to a reference type (`&_issue1231::Foo<'_, &u8>`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:37:33
|
||||
--> $DIR/transmute_ptr_to_ref.rs:38:33
|
||||
|
|
||||
LL | let _: &Foo<&u8> = unsafe { std::mem::transmute::<_, &Foo<&_>>(raw) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*raw.cast::<Foo<&_>>()`
|
||||
|
||||
error: transmute from a pointer type (`*const i32`) to a reference type (`&u8`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:41:14
|
||||
--> $DIR/transmute_ptr_to_ref.rs:42:22
|
||||
|
|
||||
LL | unsafe { std::mem::transmute::<_, Bar>(raw) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const u8)`
|
||||
LL | let _ = unsafe { std::mem::transmute::<_, Bar>(raw) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const u8)`
|
||||
|
||||
error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:46:14
|
||||
--> $DIR/transmute_ptr_to_ref.rs:47:14
|
||||
|
|
||||
LL | 0 => std::mem::transmute(x),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&u32>()`
|
||||
|
||||
error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:47:14
|
||||
--> $DIR/transmute_ptr_to_ref.rs:48:14
|
||||
|
|
||||
LL | 1 => std::mem::transmute(y),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*y.cast::<&u32>()`
|
||||
|
||||
error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:48:14
|
||||
--> $DIR/transmute_ptr_to_ref.rs:49:14
|
||||
|
|
||||
LL | 2 => std::mem::transmute::<_, &&'b u32>(x),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&'b u32>()`
|
||||
|
||||
error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:49:14
|
||||
--> $DIR/transmute_ptr_to_ref.rs:50:14
|
||||
|
|
||||
LL | _ => std::mem::transmute::<_, &&'b u32>(y),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*y.cast::<&'b u32>()`
|
||||
|
||||
error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:57:19
|
||||
--> $DIR/transmute_ptr_to_ref.rs:58:19
|
||||
|
|
||||
LL | let _: &u32 = std::mem::transmute(a);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a`
|
||||
|
||||
error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:58:19
|
||||
--> $DIR/transmute_ptr_to_ref.rs:59:19
|
||||
|
|
||||
LL | let _: &u32 = std::mem::transmute::<_, &u32>(a);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a.cast::<u32>()`
|
||||
|
||||
error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:60:14
|
||||
--> $DIR/transmute_ptr_to_ref.rs:61:14
|
||||
|
|
||||
LL | 0 => std::mem::transmute(x),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&u32>()`
|
||||
|
||||
error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:61:14
|
||||
--> $DIR/transmute_ptr_to_ref.rs:62:14
|
||||
|
|
||||
LL | _ => std::mem::transmute::<_, &&'b u32>(x),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&'b u32>()`
|
||||
|
||||
error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:69:19
|
||||
--> $DIR/transmute_ptr_to_ref.rs:70:19
|
||||
|
|
||||
LL | let _: &u32 = std::mem::transmute(a);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a`
|
||||
|
||||
error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:70:19
|
||||
--> $DIR/transmute_ptr_to_ref.rs:71:19
|
||||
|
|
||||
LL | let _: &u32 = std::mem::transmute::<_, &u32>(a);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a as *const u32)`
|
||||
|
||||
error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:72:14
|
||||
--> $DIR/transmute_ptr_to_ref.rs:73:14
|
||||
|
|
||||
LL | 0 => std::mem::transmute(x),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const () as *const &u32)`
|
||||
|
||||
error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
|
||||
--> $DIR/transmute_ptr_to_ref.rs:73:14
|
||||
--> $DIR/transmute_ptr_to_ref.rs:74:14
|
||||
|
|
||||
LL | _ => std::mem::transmute::<_, &&'b u32>(x),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const () as *const &'b u32)`
|
||||
|
@ -10,7 +10,7 @@ fn fill(v: &mut i32) {
|
||||
}
|
||||
|
||||
fn evil() {
|
||||
unsafe { &mut *(LEAK as *mut i32) }; //~ ERROR: is a dangling pointer
|
||||
let _ = unsafe { &mut *(LEAK as *mut i32) }; //~ ERROR: is a dangling pointer
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: Undefined Behavior: dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance)
|
||||
--> $DIR/storage_dead_dangling.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { &mut *(LEAK as *mut i32) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance)
|
||||
LL | let _ = unsafe { &mut *(LEAK as *mut i32) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance)
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
|
@ -2,6 +2,6 @@
|
||||
|
||||
#[allow(deprecated, invalid_value)]
|
||||
fn main() {
|
||||
unsafe { std::mem::uninitialized::<!>() };
|
||||
let _ = unsafe { std::mem::uninitialized::<!>() };
|
||||
//~^ ERROR: attempted to instantiate uninhabited type `!`
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: abnormal termination: aborted execution: attempted to instantiate uninhabited type `!`
|
||||
--> $DIR/uninit_uninhabited_type.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { std::mem::uninitialized::<!>() };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!`
|
||||
LL | let _ = unsafe { std::mem::uninitialized::<!>() };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!`
|
||||
|
|
||||
= note: inside `main` at $DIR/uninit_uninhabited_type.rs:LL:CC
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#[allow(deprecated, invalid_value)]
|
||||
fn main() {
|
||||
unsafe { std::mem::zeroed::<fn()>() };
|
||||
let _ = unsafe { std::mem::zeroed::<fn()>() };
|
||||
//~^ ERROR: attempted to zero-initialize type `fn()`, which is invalid
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: abnormal termination: aborted execution: attempted to zero-initialize type `fn()`, which is invalid
|
||||
--> $DIR/zero_fn_ptr.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { std::mem::zeroed::<fn()>() };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to zero-initialize type `fn()`, which is invalid
|
||||
LL | let _ = unsafe { std::mem::zeroed::<fn()>() };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to zero-initialize type `fn()`, which is invalid
|
||||
|
|
||||
= note: inside `main` at $DIR/zero_fn_ptr.rs:LL:CC
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
warning: unused closure that must be used
|
||||
--> $DIR/issue-1460.rs:6:5
|
||||
--> $DIR/issue-1460.rs:6:6
|
||||
|
|
||||
LL | {|i: u32| if 1 == i { }};
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: closures are lazy and do nothing unless called
|
||||
= note: `#[warn(unused_must_use)]` on by default
|
||||
|
36
tests/ui/lint/unused/must-use-block-expr.fixed
Normal file
36
tests/ui/lint/unused/must-use-block-expr.fixed
Normal file
@ -0,0 +1,36 @@
|
||||
// run-rustfix
|
||||
// check-pass
|
||||
|
||||
#![warn(unused_must_use)]
|
||||
|
||||
#[must_use]
|
||||
fn foo() -> i32 {
|
||||
42
|
||||
}
|
||||
|
||||
fn bar() {
|
||||
{
|
||||
let _ = foo();
|
||||
//~^ WARN unused return value
|
||||
}
|
||||
}
|
||||
|
||||
fn baz() {
|
||||
{
|
||||
let _ = foo();
|
||||
//~^ WARN unused return value
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
bar();
|
||||
baz();
|
||||
{
|
||||
let _ = 1 + 2;
|
||||
//~^ WARN unused arithmetic operation
|
||||
}
|
||||
{
|
||||
let _ = 1 + 2;
|
||||
//~^ WARN unused arithmetic operation
|
||||
};
|
||||
}
|
36
tests/ui/lint/unused/must-use-block-expr.rs
Normal file
36
tests/ui/lint/unused/must-use-block-expr.rs
Normal file
@ -0,0 +1,36 @@
|
||||
// run-rustfix
|
||||
// check-pass
|
||||
|
||||
#![warn(unused_must_use)]
|
||||
|
||||
#[must_use]
|
||||
fn foo() -> i32 {
|
||||
42
|
||||
}
|
||||
|
||||
fn bar() {
|
||||
{
|
||||
foo();
|
||||
//~^ WARN unused return value
|
||||
}
|
||||
}
|
||||
|
||||
fn baz() {
|
||||
{
|
||||
foo()
|
||||
//~^ WARN unused return value
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
bar();
|
||||
baz();
|
||||
{
|
||||
1 + 2;
|
||||
//~^ WARN unused arithmetic operation
|
||||
}
|
||||
{
|
||||
1 + 2
|
||||
//~^ WARN unused arithmetic operation
|
||||
};
|
||||
}
|
51
tests/ui/lint/unused/must-use-block-expr.stderr
Normal file
51
tests/ui/lint/unused/must-use-block-expr.stderr
Normal file
@ -0,0 +1,51 @@
|
||||
warning: unused return value of `foo` that must be used
|
||||
--> $DIR/must-use-block-expr.rs:13:9
|
||||
|
|
||||
LL | foo();
|
||||
| ^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/must-use-block-expr.rs:4:9
|
||||
|
|
||||
LL | #![warn(unused_must_use)]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
help: use `let _ = ...` to ignore the resulting value
|
||||
|
|
||||
LL | let _ = foo();
|
||||
| +++++++
|
||||
|
||||
warning: unused return value of `foo` that must be used
|
||||
--> $DIR/must-use-block-expr.rs:20:9
|
||||
|
|
||||
LL | foo()
|
||||
| ^^^^^
|
||||
|
|
||||
help: use `let _ = ...` to ignore the resulting value
|
||||
|
|
||||
LL | let _ = foo();
|
||||
| +++++++ +
|
||||
|
||||
warning: unused arithmetic operation that must be used
|
||||
--> $DIR/must-use-block-expr.rs:29:9
|
||||
|
|
||||
LL | 1 + 2;
|
||||
| ^^^^^ the arithmetic operation produces a value
|
||||
|
|
||||
help: use `let _ = ...` to ignore the resulting value
|
||||
|
|
||||
LL | let _ = 1 + 2;
|
||||
| +++++++
|
||||
|
||||
warning: unused arithmetic operation that must be used
|
||||
--> $DIR/must-use-block-expr.rs:33:9
|
||||
|
|
||||
LL | 1 + 2
|
||||
| ^^^^^ the arithmetic operation produces a value
|
||||
|
|
||||
help: use `let _ = ...` to ignore the resulting value
|
||||
|
|
||||
LL | let _ = 1 + 2;
|
||||
| +++++++ +
|
||||
|
||||
warning: 4 warnings emitted
|
||||
|
Loading…
Reference in New Issue
Block a user