mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-14 00:47:16 +00:00
[missing_const_for_fn
]: fix FP when arg ty is impl trait alias ty
This commit is contained in:
parent
0aac16e5b2
commit
08992d0372
5 changed files with 68 additions and 1 deletions
|
@ -8,6 +8,7 @@ use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{self as hir, Body, Constness, FnDecl, GenericParamKind};
|
use rustc_hir::{self as hir, Body, Constness, FnDecl, GenericParamKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
|
use rustc_middle::ty;
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::def_id::LocalDefId;
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -131,6 +132,10 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
|
||||||
FnKind::Closure => return,
|
FnKind::Closure => return,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if fn_inputs_has_impl_trait_ty(cx, def_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let hir_id = cx.tcx.local_def_id_to_hir_id(def_id);
|
let hir_id = cx.tcx.local_def_id_to_hir_id(def_id);
|
||||||
|
|
||||||
// Const fns are not allowed as methods in a trait.
|
// Const fns are not allowed as methods in a trait.
|
||||||
|
@ -185,3 +190,15 @@ fn could_be_const_with_abi(cx: &LateContext<'_>, msrv: &Msrv, abi: Abi) -> bool
|
||||||
_ => cx.tcx.features().const_extern_fn,
|
_ => cx.tcx.features().const_extern_fn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return `true` when the given `def_id` is a function that has `impl Trait` ty as one of
|
||||||
|
/// its parameter types.
|
||||||
|
fn fn_inputs_has_impl_trait_ty(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {
|
||||||
|
let inputs = cx.tcx.fn_sig(def_id).instantiate_identity().inputs().skip_binder();
|
||||||
|
inputs.iter().any(|input| {
|
||||||
|
matches!(
|
||||||
|
input.kind(),
|
||||||
|
ty::Alias(ty::AliasTyKind::Weak, alias_ty) if cx.tcx.type_of(alias_ty.def_id).skip_binder().is_impl_trait()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#![warn(clippy::missing_const_for_fn)]
|
#![warn(clippy::missing_const_for_fn)]
|
||||||
#![feature(start)]
|
#![feature(start)]
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
extern crate helper;
|
extern crate helper;
|
||||||
extern crate proc_macros;
|
extern crate proc_macros;
|
||||||
|
@ -190,3 +191,11 @@ mod with_extern {
|
||||||
extern "system" fn system() {}
|
extern "system" fn system() {}
|
||||||
extern "system-unwind" fn system_unwind() {}
|
extern "system-unwind" fn system_unwind() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod with_ty_alias {
|
||||||
|
type Foo = impl std::fmt::Debug;
|
||||||
|
|
||||||
|
fn foo(_: Foo) {
|
||||||
|
let _: Foo = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -186,3 +186,18 @@ mod issue12677 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod with_ty_alias {
|
||||||
|
trait FooTrait {
|
||||||
|
type Foo: std::fmt::Debug;
|
||||||
|
fn bar(_: Self::Foo) {}
|
||||||
|
}
|
||||||
|
impl FooTrait for () {
|
||||||
|
type Foo = i32;
|
||||||
|
}
|
||||||
|
// NOTE: When checking the type of a function param, make sure it is not an alias with
|
||||||
|
// `AliasTyKind::Projection` before calling `TyCtxt::type_of` to find out what the actual type
|
||||||
|
// is. Because the associate ty could have no default, therefore would cause ICE, as demostrated
|
||||||
|
// in this test.
|
||||||
|
const fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
|
||||||
|
}
|
||||||
|
|
|
@ -186,3 +186,18 @@ mod issue12677 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod with_ty_alias {
|
||||||
|
trait FooTrait {
|
||||||
|
type Foo: std::fmt::Debug;
|
||||||
|
fn bar(_: Self::Foo) {}
|
||||||
|
}
|
||||||
|
impl FooTrait for () {
|
||||||
|
type Foo = i32;
|
||||||
|
}
|
||||||
|
// NOTE: When checking the type of a function param, make sure it is not an alias with
|
||||||
|
// `AliasTyKind::Projection` before calling `TyCtxt::type_of` to find out what the actual type
|
||||||
|
// is. Because the associate ty could have no default, therefore would cause ICE, as demostrated
|
||||||
|
// in this test.
|
||||||
|
fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
|
||||||
|
}
|
||||||
|
|
|
@ -261,5 +261,16 @@ help: make the function `const`
|
||||||
LL | pub const fn new(text: String) -> Self {
|
LL | pub const fn new(text: String) -> Self {
|
||||||
| +++++
|
| +++++
|
||||||
|
|
||||||
error: aborting due to 19 previous errors
|
error: this could be a `const fn`
|
||||||
|
--> tests/ui/missing_const_for_fn/could_be_const.rs:202:5
|
||||||
|
|
|
||||||
|
LL | fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: make the function `const`
|
||||||
|
|
|
||||||
|
LL | const fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error: aborting due to 20 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue