Skip to content

False "missing_const_in_fn" for a function that consumes self #8874

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ppentchev opened this issue May 23, 2022 · 4 comments
Open

False "missing_const_in_fn" for a function that consumes self #8874

ppentchev opened this issue May 23, 2022 · 4 comments
Labels
C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have L-nursery Lint: Currently in the nursery group

Comments

@ppentchev
Copy link

ppentchev commented May 23, 2022

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

@ppentchev ppentchev added C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have labels May 23, 2022
@BurntNail
Copy link

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.

@mahlquistj
Copy link

mahlquistj commented Jul 4, 2023

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.

@Centri3
Copy link
Member

Centri3 commented Jul 4, 2023

I believe this was already fixed in #10891.

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=7c430738d1e182a7bbb03c1ba398d1da

@johnperry-math
Copy link

johnperry-math commented Jan 16, 2024

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.

@J-ZhengLi J-ZhengLi added the L-nursery Lint: Currently in the nursery group label Apr 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have L-nursery Lint: Currently in the nursery group
Projects
None yet
Development

No branches or pull requests

6 participants