rust-clippy
rust-clippy copied to clipboard
False "missing_const_in_fn" for a function that consumes `self`
Summary
Hi,
First of all, thanks a lot for working on Rust and the related tools and crates!
Clippy seems to report a "missing_const_in_fn" for a function that replaces a field in a struct. If I add "const" to the function, rustc says "constant functions cannot evaluate destructors". It is quite possible that, just like e.g. #4041, this is actually a bug in rustc's parser, AST builder, code analyzer, etc; apologies if it has been reported already.
Since the source file is a bit on the large side, I have put the mini-"crate" up in a Git repository at https://gitlab.com/ppentchev/rust-bug-missing-const
Lint Name
clippy::missing_const_for_fn
Reproducer
I tried this code (it uses expect-exit 0.4.2):
/*
* Copyright (c) 2022 Peter Pentchev <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
//! Demonstrate a false `clippy::missing_const_for_fn` positive.
#![deny(missing_docs)]
// Activate most of the clippy::restriction lints that we've encountered...
#![warn(clippy::pattern_type_mismatch)]
#![warn(clippy::missing_docs_in_private_items)]
#![warn(clippy::print_stdout)]
// ...except for these ones.
#![allow(clippy::implicit_return)]
// Activate some of the clippy::nursery lints...
#![warn(clippy::missing_const_for_fn)]
use std::env;
/// Runtime configuration for the bug-missing-const tool.
#[derive(Debug, PartialEq)]
#[non_exhaustive]
struct Config {
/// The current program name.
program: String,
}
impl Default for Config {
fn default() -> Self {
Self {
program: "(unspecified)".to_owned(),
}
}
}
impl Config {
/// Specify the program name.
fn with_program(self, program: String) -> Self {
Self { program, ..self }
}
}
/// Parse the command-line arguments into a configuration structure.
fn parse_args() -> Config {
let args: Vec<String> = env::args().collect();
match *args {
[] => expect_exit::exit("Not even a program name?"),
[ref program] => Config::default().with_program(program.clone()),
_ => expect_exit::exit("Usage: bug-missing-const"),
}
}
#[cfg(test)]
mod tests {
use super::Config;
#[test]
fn test_config_default() {
assert!(
Config::default()
== Config {
program: "(unspecified)".to_owned()
}
);
}
#[test]
fn test_config_with_program() {
assert!(
Config::default().with_program("616".to_owned())
== Config {
program: "616".to_owned()
}
);
}
}
#[allow(clippy::print_stdout)]
fn main() {
let cfg = parse_args();
println!("Program name: {}", cfg.program);
}
I saw this happen:
Checking bug-missing-const v0.1.0 (/home/roam/lang/rust/misc/bug-missing-const)
warning: this could be a `const fn`
--> src/main.rs:58:5
|
58 | / fn with_program(self, program: String) -> Self {
59 | | Self { program, ..self }
60 | | }
| |_____^
I expected to see no warnings at all.
Version
rustc 1.61.0 (fe5b13d68 2022-05-18)
binary: rustc
commit-hash: fe5b13d681f25ee6474be29d748c65adcd91f69e
commit-date: 2022-05-18
host: x86_64-unknown-linux-gnu
release: 1.61.0
LLVM version: 14.0.0
Additional Labels
No response
I'm also experiencing this issue - the code that triggers it follows:
pub enum Either<A, B> {
Left(A),
Right(B)
}
impl<A> Either<A, A> {
pub fn unwrap (self) -> A {
match self {
Self::Left(a) => a,
Self::Right(b) => b
}
}
}
error as follows:
warning: this could be a `const fn`
--> src\either.rs:16:5
|
16 | / pub fn unwrap (self) -> A {
17 | | match self {
18 | | Self::Left(a) => a,
19 | | Self::Right(b) => b
20 | | }
21 | | }
| |_____^
Error line is incorrect due to removed code - not clippy's fault.
I can also pitch in with my experience.
I have a struct with a generic:
pub struct Response<V> {
ok: bool,
value: Option<V>,
}
Which implements the following function:
fn value(self) -> Option<V> {
self.value
}
Clippy suggests making the function a const fn
but when i do so, the compiler tells me the following:
error[E0493]: destructor of `core::response::Response<V>` cannot be evaluated at compile-time
--> src/core/response.rs:82:20
|
82 | const fn value(self) -> Option<V> {
| ^^^^ the destructor for this type cannot be evaluated in constant functions
83 | self.value
84 | }
| - value is dropped here
Note: The struct has other fields and more implementations, but the above is the "minimal" example of the issue. If more is needed, i will happily provide it.
I believe this was already fixed in #10891.
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=7c430738d1e182a7bbb03c1ba398d1da
I believe this was already fixed in #10891.
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=7c430738d1e182a7bbb03c1ba398d1da
When using Rust 1.75, I still see this clippy warning on a straightforward builder pattern and clippy::nursery
.