Skip to content

Commit

Permalink
Prevent missing_const_for_fn on functions with const generic params
Browse files Browse the repository at this point in the history
`const` functions cannot have const generic parameters so prevent the
`missing_const_for_fn` lint from firing in that case.
  • Loading branch information
krishna-veerareddy committed Feb 22, 2020
1 parent e342047 commit 0490798
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 14 deletions.
12 changes: 9 additions & 3 deletions clippy_lints/src/missing_const_for_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ use crate::utils::{has_drop, is_entrypoint_fn, span_lint, trait_ref_of_method};
use rustc::lint::in_external_macro;
use rustc_hir as hir;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, Constness, FnDecl, HirId};
use rustc_hir::{Body, Constness, FnDecl, GenericParamKind, HirId};
use rustc_lint::{LateContext, LateLintPass};
use rustc_mir::transform::qualify_min_const_fn::is_min_const_fn;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::Span;
use rustc_typeck::hir_ty_to_ty;
use std::matches;

declare_clippy_lint! {
/// **What it does:**
Expand Down Expand Up @@ -90,8 +91,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingConstForFn {
// Perform some preliminary checks that rule out constness on the Clippy side. This way we
// can skip the actual const check and return early.
match kind {
FnKind::ItemFn(_, _, header, ..) => {
if already_const(header) {
FnKind::ItemFn(_, generics, header, ..) => {
let has_const_generic_params = generics
.params
.iter()
.any(|param| matches!(param.kind, GenericParamKind::Const{ .. }));

if already_const(header) || has_const_generic_params {
return;
}
},
Expand Down
13 changes: 12 additions & 1 deletion tests/ui/missing_const_for_fn/cant_be_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
//! The .stderr output of this test should be empty. Otherwise it's a bug somewhere.

#![warn(clippy::missing_const_for_fn)]
#![feature(start)]
#![allow(incomplete_features)]
#![feature(start, const_generics)]

struct Game;

Expand Down Expand Up @@ -90,3 +91,13 @@ mod with_drop {
}
}
}

fn const_generic_params<T, const N: usize>(t: &[T; N]) -> &[T; N] {
t
}

fn const_generic_return<T, const N: usize>(t: &[T]) -> &[T; N] {
let p = t.as_ptr() as *const [T; N];

unsafe { &*p }
}
7 changes: 6 additions & 1 deletion tests/ui/missing_const_for_fn/could_be_const.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![warn(clippy::missing_const_for_fn)]
#![allow(clippy::let_and_return)]
#![allow(incomplete_features, clippy::let_and_return)]
#![feature(const_generics)]

use std::mem::transmute;

Expand All @@ -12,6 +13,10 @@ impl Game {
pub fn new() -> Self {
Self { guess: 42 }
}

fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] {
b
}
}

// Could be const
Expand Down
26 changes: 17 additions & 9 deletions tests/ui/missing_const_for_fn/could_be_const.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: this could be a `const fn`
--> $DIR/could_be_const.rs:12:5
--> $DIR/could_be_const.rs:13:5
|
LL | / pub fn new() -> Self {
LL | | Self { guess: 42 }
Expand All @@ -9,15 +9,23 @@ LL | | }
= note: `-D clippy::missing-const-for-fn` implied by `-D warnings`

error: this could be a `const fn`
--> $DIR/could_be_const.rs:18:1
--> $DIR/could_be_const.rs:17:5
|
LL | / fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] {
LL | | b
LL | | }
| |_____^

error: this could be a `const fn`
--> $DIR/could_be_const.rs:23:1
|
LL | / fn one() -> i32 {
LL | | 1
LL | | }
| |_^

error: this could be a `const fn`
--> $DIR/could_be_const.rs:23:1
--> $DIR/could_be_const.rs:28:1
|
LL | / fn two() -> i32 {
LL | | let abc = 2;
Expand All @@ -26,44 +34,44 @@ LL | | }
| |_^

error: this could be a `const fn`
--> $DIR/could_be_const.rs:29:1
--> $DIR/could_be_const.rs:34:1
|
LL | / fn string() -> String {
LL | | String::new()
LL | | }
| |_^

error: this could be a `const fn`
--> $DIR/could_be_const.rs:34:1
--> $DIR/could_be_const.rs:39:1
|
LL | / unsafe fn four() -> i32 {
LL | | 4
LL | | }
| |_^

error: this could be a `const fn`
--> $DIR/could_be_const.rs:39:1
--> $DIR/could_be_const.rs:44:1
|
LL | / fn generic<T>(t: T) -> T {
LL | | t
LL | | }
| |_^

error: this could be a `const fn`
--> $DIR/could_be_const.rs:43:1
--> $DIR/could_be_const.rs:48:1
|
LL | / fn sub(x: u32) -> usize {
LL | | unsafe { transmute(&x) }
LL | | }
| |_^

error: this could be a `const fn`
--> $DIR/could_be_const.rs:62:9
--> $DIR/could_be_const.rs:67:9
|
LL | / pub fn b(self, a: &A) -> B {
LL | | B
LL | | }
| |_________^

error: aborting due to 8 previous errors
error: aborting due to 9 previous errors

0 comments on commit 0490798

Please sign in to comment.