Skip to content

Commit 2ad8cdc

Browse files
committed
Auto merge of rust-lang#13045 - J-ZhengLi:missing_const_for_fn_FP, r=blyxyas
[`missing_const_for_fn`]: fix FP when arg ty is impl trait alias ty closes: rust-lang#13009 --- changelog: [`missing_const_for_fn`]: fix FP when arg ty is impl trait alias ty
2 parents 1de41b1 + 08992d0 commit 2ad8cdc

File tree

5 files changed

+68
-1
lines changed

5 files changed

+68
-1
lines changed

clippy_lints/src/missing_const_for_fn.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_hir::intravisit::FnKind;
88
use rustc_hir::{self as hir, Body, Constness, FnDecl, GenericParamKind};
99
use rustc_lint::{LateContext, LateLintPass};
1010
use rustc_middle::lint::in_external_macro;
11+
use rustc_middle::ty;
1112
use rustc_session::impl_lint_pass;
1213
use rustc_span::def_id::LocalDefId;
1314
use rustc_span::Span;
@@ -131,6 +132,10 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
131132
FnKind::Closure => return,
132133
}
133134

135+
if fn_inputs_has_impl_trait_ty(cx, def_id) {
136+
return;
137+
}
138+
134139
let hir_id = cx.tcx.local_def_id_to_hir_id(def_id);
135140

136141
// 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
185190
_ => cx.tcx.features().const_extern_fn,
186191
}
187192
}
193+
194+
/// Return `true` when the given `def_id` is a function that has `impl Trait` ty as one of
195+
/// its parameter types.
196+
fn fn_inputs_has_impl_trait_ty(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {
197+
let inputs = cx.tcx.fn_sig(def_id).instantiate_identity().inputs().skip_binder();
198+
inputs.iter().any(|input| {
199+
matches!(
200+
input.kind(),
201+
ty::Alias(ty::AliasTyKind::Weak, alias_ty) if cx.tcx.type_of(alias_ty.def_id).skip_binder().is_impl_trait()
202+
)
203+
})
204+
}

tests/ui/missing_const_for_fn/cant_be_const.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#![warn(clippy::missing_const_for_fn)]
99
#![feature(start)]
10+
#![feature(type_alias_impl_trait)]
1011

1112
extern crate helper;
1213
extern crate proc_macros;
@@ -190,3 +191,11 @@ mod with_extern {
190191
extern "system" fn system() {}
191192
extern "system-unwind" fn system_unwind() {}
192193
}
194+
195+
mod with_ty_alias {
196+
type Foo = impl std::fmt::Debug;
197+
198+
fn foo(_: Foo) {
199+
let _: Foo = 1;
200+
}
201+
}

tests/ui/missing_const_for_fn/could_be_const.fixed

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,3 +186,18 @@ mod issue12677 {
186186
}
187187
}
188188
}
189+
190+
mod with_ty_alias {
191+
trait FooTrait {
192+
type Foo: std::fmt::Debug;
193+
fn bar(_: Self::Foo) {}
194+
}
195+
impl FooTrait for () {
196+
type Foo = i32;
197+
}
198+
// NOTE: When checking the type of a function param, make sure it is not an alias with
199+
// `AliasTyKind::Projection` before calling `TyCtxt::type_of` to find out what the actual type
200+
// is. Because the associate ty could have no default, therefore would cause ICE, as demostrated
201+
// in this test.
202+
const fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
203+
}

tests/ui/missing_const_for_fn/could_be_const.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,3 +186,18 @@ mod issue12677 {
186186
}
187187
}
188188
}
189+
190+
mod with_ty_alias {
191+
trait FooTrait {
192+
type Foo: std::fmt::Debug;
193+
fn bar(_: Self::Foo) {}
194+
}
195+
impl FooTrait for () {
196+
type Foo = i32;
197+
}
198+
// NOTE: When checking the type of a function param, make sure it is not an alias with
199+
// `AliasTyKind::Projection` before calling `TyCtxt::type_of` to find out what the actual type
200+
// is. Because the associate ty could have no default, therefore would cause ICE, as demostrated
201+
// in this test.
202+
fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
203+
}

tests/ui/missing_const_for_fn/could_be_const.stderr

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,5 +261,16 @@ help: make the function `const`
261261
LL | pub const fn new(text: String) -> Self {
262262
| +++++
263263

264-
error: aborting due to 19 previous errors
264+
error: this could be a `const fn`
265+
--> tests/ui/missing_const_for_fn/could_be_const.rs:202:5
266+
|
267+
LL | fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
268+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
269+
|
270+
help: make the function `const`
271+
|
272+
LL | const fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
273+
| +++++
274+
275+
error: aborting due to 20 previous errors
265276

0 commit comments

Comments
 (0)