diff --git a/compiler/rustc_mir/src/transform/function_item_references.rs b/compiler/rustc_mir/src/transform/function_item_references.rs index 3a30b41d6816f..61427422e4b59 100644 --- a/compiler/rustc_mir/src/transform/function_item_references.rs +++ b/compiler/rustc_mir/src/transform/function_item_references.rs @@ -1,3 +1,4 @@ +use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; @@ -183,16 +184,22 @@ impl<'a, 'tcx> FunctionItemRefChecker<'a, 'tcx> { let variadic = if fn_sig.c_variadic() { ", ..." } else { "" }; let ret = if fn_sig.output().skip_binder().is_unit() { "" } else { " -> _" }; self.tcx.struct_span_lint_hir(FUNCTION_ITEM_REFERENCES, lint_root, span, |lint| { - lint.build(&format!( - "cast `{}` with `as {}{}fn({}{}){}` to obtain a function pointer", - ident, - unsafety, - abi, - vec!["_"; num_args].join(", "), - variadic, - ret, - )) - .emit(); + lint.build("taking a reference to a function item does not give a function pointer") + .span_suggestion( + span, + &format!("cast `{}` to obtain a function pointer", ident), + format!( + "{} as {}{}fn({}{}){}", + ident, + unsafety, + abi, + vec!["_"; num_args].join(", "), + variadic, + ret, + ), + Applicability::Unspecified, + ) + .emit(); }); } } diff --git a/compiler/rustc_session/src/lint/builtin.rs b/compiler/rustc_session/src/lint/builtin.rs index 806f79af277b0..b8826a548b8be 100644 --- a/compiler/rustc_session/src/lint/builtin.rs +++ b/compiler/rustc_session/src/lint/builtin.rs @@ -2674,7 +2674,7 @@ declare_lint! { /// arguments bound by [`fmt::Pointer`] or transmuted. pub FUNCTION_ITEM_REFERENCES, Warn, - "suggest casting functions to pointers when attempting to take references", + "suggest casting to a function pointer when attempting to take references to function items", } declare_lint! { diff --git a/src/test/ui/lint/function-item-references.rs b/src/test/ui/lint/function-item-references.rs index 28c66a31322c4..439b56967d072 100644 --- a/src/test/ui/lint/function-item-references.rs +++ b/src/test/ui/lint/function-item-references.rs @@ -38,7 +38,7 @@ fn _format_assoc_item(data: T, f: &mut Formatter) -> std::fmt::Resul fn _call_pointer_fmt(f: &mut Formatter) -> std::fmt::Result { let zst_ref = &foo; Pointer::fmt(&zst_ref, f) - //~^ WARNING cast `foo` with `as fn() -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer } fn main() { @@ -75,47 +75,47 @@ fn main() { //potential ways to incorrectly try printing function pointers println!("{:p}", &foo); - //~^ WARNING cast `foo` with `as fn() -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer print!("{:p}", &foo); - //~^ WARNING cast `foo` with `as fn() -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer format!("{:p}", &foo); - //~^ WARNING cast `foo` with `as fn() -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer println!("{:p}", &foo as *const _); - //~^ WARNING cast `foo` with `as fn() -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer println!("{:p}", zst_ref); - //~^ WARNING cast `foo` with `as fn() -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer println!("{:p}", cast_zst_ptr); - //~^ WARNING cast `foo` with `as fn() -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer println!("{:p}", coerced_zst_ptr); - //~^ WARNING cast `foo` with `as fn() -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer println!("{:p}", &fn_item); - //~^ WARNING cast `foo` with `as fn() -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer println!("{:p}", indirect_ref); - //~^ WARNING cast `foo` with `as fn() -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer println!("{:p}", &nop); - //~^ WARNING cast `nop` with `as fn()` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer println!("{:p}", &bar); - //~^ WARNING cast `bar` with `as fn(_) -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer println!("{:p}", &baz); - //~^ WARNING cast `baz` with `as fn(_, _) -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer println!("{:p}", &unsafe_fn); - //~^ WARNING cast `unsafe_fn` with `as unsafe fn()` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer println!("{:p}", &c_fn); - //~^ WARNING cast `c_fn` with `as extern "C" fn()` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer println!("{:p}", &unsafe_c_fn); - //~^ WARNING cast `unsafe_c_fn` with `as unsafe extern "C" fn()` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer println!("{:p}", &variadic); - //~^ WARNING cast `variadic` with `as unsafe extern "C" fn(_, ...)` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer println!("{:p}", &std::env::var::); - //~^ WARNING cast `var` with `as fn(_) -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer println!("{:p} {:p} {:p}", &nop, &foo, &bar); - //~^ WARNING cast `nop` with `as fn()` to obtain a function pointer - //~^^ WARNING cast `foo` with `as fn() -> _` to obtain a function pointer - //~^^^ WARNING cast `bar` with `as fn(_) -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer + //~^^ WARNING taking a reference to a function item does not give a function pointer + //~^^^ WARNING taking a reference to a function item does not give a function pointer //using a function reference to call a function shouldn't lint (&bar)(1); @@ -128,10 +128,10 @@ fn main() { unsafe { //potential ways to incorrectly try transmuting function pointers std::mem::transmute::<_, usize>(&foo); - //~^ WARNING cast `foo` with `as fn() -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer std::mem::transmute::<_, (usize, usize)>((&foo, &bar)); - //~^ WARNING cast `foo` with `as fn() -> _` to obtain a function pointer - //~^^ WARNING cast `bar` with `as fn(_) -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer + //~^^ WARNING taking a reference to a function item does not give a function pointer //the correct way to transmute function pointers std::mem::transmute::<_, usize>(foo as fn() -> u32); @@ -140,12 +140,12 @@ fn main() { //function references as arguments required to be bound by std::fmt::Pointer should lint print_ptr(&bar); - //~^ WARNING cast `bar` with `as fn(_) -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer bound_by_ptr_trait(&bar); - //~^ WARNING cast `bar` with `as fn(_) -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer bound_by_ptr_trait_tuple((&foo, &bar)); - //~^ WARNING cast `foo` with `as fn() -> _` to obtain a function pointer - //~^^ WARNING cast `bar` with `as fn(_) -> _` to obtain a function pointer + //~^ WARNING taking a reference to a function item does not give a function pointer + //~^^ WARNING taking a reference to a function item does not give a function pointer implicit_ptr_trait(&bar); // ignore //correct ways to pass function pointers as arguments bound by std::fmt::Pointer diff --git a/src/test/ui/lint/function-item-references.stderr b/src/test/ui/lint/function-item-references.stderr index a96b134ed580f..610dff04e6edf 100644 --- a/src/test/ui/lint/function-item-references.stderr +++ b/src/test/ui/lint/function-item-references.stderr @@ -1,8 +1,8 @@ -warning: cast `foo` with `as fn() -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:40:18 | LL | Pointer::fmt(&zst_ref, f) - | ^^^^^^^^ + | ^^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _` | note: the lint level is defined here --> $DIR/function-item-references.rs:3:9 @@ -10,167 +10,167 @@ note: the lint level is defined here LL | #![warn(function_item_references)] | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: cast `foo` with `as fn() -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:77:22 | LL | println!("{:p}", &foo); - | ^^^^ + | ^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _` -warning: cast `foo` with `as fn() -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:79:20 | LL | print!("{:p}", &foo); - | ^^^^ + | ^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _` -warning: cast `foo` with `as fn() -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:81:21 | LL | format!("{:p}", &foo); - | ^^^^ + | ^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _` -warning: cast `foo` with `as fn() -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:84:22 | LL | println!("{:p}", &foo as *const _); - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _` -warning: cast `foo` with `as fn() -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:86:22 | LL | println!("{:p}", zst_ref); - | ^^^^^^^ + | ^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _` -warning: cast `foo` with `as fn() -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:88:22 | LL | println!("{:p}", cast_zst_ptr); - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _` -warning: cast `foo` with `as fn() -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:90:22 | LL | println!("{:p}", coerced_zst_ptr); - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _` -warning: cast `foo` with `as fn() -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:93:22 | LL | println!("{:p}", &fn_item); - | ^^^^^^^^ + | ^^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _` -warning: cast `foo` with `as fn() -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:95:22 | LL | println!("{:p}", indirect_ref); - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _` -warning: cast `nop` with `as fn()` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:98:22 | LL | println!("{:p}", &nop); - | ^^^^ + | ^^^^ help: cast `nop` to obtain a function pointer: `nop as fn()` -warning: cast `bar` with `as fn(_) -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:100:22 | LL | println!("{:p}", &bar); - | ^^^^ + | ^^^^ help: cast `bar` to obtain a function pointer: `bar as fn(_) -> _` -warning: cast `baz` with `as fn(_, _) -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:102:22 | LL | println!("{:p}", &baz); - | ^^^^ + | ^^^^ help: cast `baz` to obtain a function pointer: `baz as fn(_, _) -> _` -warning: cast `unsafe_fn` with `as unsafe fn()` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:104:22 | LL | println!("{:p}", &unsafe_fn); - | ^^^^^^^^^^ + | ^^^^^^^^^^ help: cast `unsafe_fn` to obtain a function pointer: `unsafe_fn as unsafe fn()` -warning: cast `c_fn` with `as extern "C" fn()` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:106:22 | LL | println!("{:p}", &c_fn); - | ^^^^^ + | ^^^^^ help: cast `c_fn` to obtain a function pointer: `c_fn as extern "C" fn()` -warning: cast `unsafe_c_fn` with `as unsafe extern "C" fn()` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:108:22 | LL | println!("{:p}", &unsafe_c_fn); - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ help: cast `unsafe_c_fn` to obtain a function pointer: `unsafe_c_fn as unsafe extern "C" fn()` -warning: cast `variadic` with `as unsafe extern "C" fn(_, ...)` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:110:22 | LL | println!("{:p}", &variadic); - | ^^^^^^^^^ + | ^^^^^^^^^ help: cast `variadic` to obtain a function pointer: `variadic as unsafe extern "C" fn(_, ...)` -warning: cast `var` with `as fn(_) -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:112:22 | LL | println!("{:p}", &std::env::var::); - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: cast `var` to obtain a function pointer: `var as fn(_) -> _` -warning: cast `nop` with `as fn()` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:115:32 | LL | println!("{:p} {:p} {:p}", &nop, &foo, &bar); - | ^^^^ + | ^^^^ help: cast `nop` to obtain a function pointer: `nop as fn()` -warning: cast `foo` with `as fn() -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:115:38 | LL | println!("{:p} {:p} {:p}", &nop, &foo, &bar); - | ^^^^ + | ^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _` -warning: cast `bar` with `as fn(_) -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:115:44 | LL | println!("{:p} {:p} {:p}", &nop, &foo, &bar); - | ^^^^ + | ^^^^ help: cast `bar` to obtain a function pointer: `bar as fn(_) -> _` -warning: cast `foo` with `as fn() -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:130:41 | LL | std::mem::transmute::<_, usize>(&foo); - | ^^^^ + | ^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _` -warning: cast `foo` with `as fn() -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:132:50 | LL | std::mem::transmute::<_, (usize, usize)>((&foo, &bar)); - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _` -warning: cast `bar` with `as fn(_) -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:132:50 | LL | std::mem::transmute::<_, (usize, usize)>((&foo, &bar)); - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ help: cast `bar` to obtain a function pointer: `bar as fn(_) -> _` -warning: cast `bar` with `as fn(_) -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:142:15 | LL | print_ptr(&bar); - | ^^^^ + | ^^^^ help: cast `bar` to obtain a function pointer: `bar as fn(_) -> _` -warning: cast `bar` with `as fn(_) -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:144:24 | LL | bound_by_ptr_trait(&bar); - | ^^^^ + | ^^^^ help: cast `bar` to obtain a function pointer: `bar as fn(_) -> _` -warning: cast `bar` with `as fn(_) -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:146:30 | LL | bound_by_ptr_trait_tuple((&foo, &bar)); - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ help: cast `bar` to obtain a function pointer: `bar as fn(_) -> _` -warning: cast `foo` with `as fn() -> _` to obtain a function pointer +warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:146:30 | LL | bound_by_ptr_trait_tuple((&foo, &bar)); - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _` warning: 28 warnings emitted