Skip to content

Effects soundness hole: Non-const assoc fns in const fns accepted if the trait is not #[const_trait] #125831

Closed
@clarfonthey

Description

@clarfonthey

I tried this code:

#![feature(effects)]
enum FlipFlop {
    Flip,
    Flop,
}
impl FlipFlop {
    const fn negating(self) -> FlipFlop {
        !self
    }
}
impl core::ops::Not for FlipFlop {
    type Output = FlipFlop;
    fn not(self) -> FlipFlop {
        match self {
            FlipFlop::Flip => FlipFlop::Flop,
            FlipFlop::Flop => FlipFlop::Flip,
        }
    }
}

I expected this code to fail, since impl Not for FlipFlop is not a constant implementation, but const fn negating requires a constant implementation.

Instead, this code succeeds with no error, failing if you actually use the method like so:

const FLOP: FlipFlop = !FlipFlop::Flip;

Giving the following result:

error[E0080]: evaluation of constant value failed
  --> src/lib.rs:21:24
   |
21 | const FLOP: FlipFlop = !FlipFlop::Flip;
   |                        ^^^^^^^^^^^^^^^ calling non-const function `<FlipFlop as Not>::not`

For more information about this error, try `rustc --explain E0080`.
error: could not compile `playground` (lib) due to 1 previous error

I believe that this code should fail to compile regardless of whether it's used at constant time.

Meta

rustc --version --verbose:

1.80.0-nightly (2024-05-30 6f3df08aadf71e8d4bf7)

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.F-effects`#![feature(effects)]`PG-const-traitsProject group: Const traitsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions