Skip to content

Terse diagnostic on lack of ~const bound in inherent associated const functions #126975

@alestane

Description

@alestane

When a trait is used as a bounds to a generic inherent implementation, and that inherent implementation defines a const function, methods from that bounding trait are not being handled as const inside that definition.

I tried this code:

#![feature(const_trait_impl)]

#[const_trait]
trait Foo {
  fn bar(&self) -> u16;
}

struct Baz<F: Foo>(F, u16);

impl<F: Foo> Baz<F> {
  const fn bat(f: F) -> u16 { f.bar() }
}

I expected to see this happen: The code would compile and use the const bar() method implemented on F.

Instead, this happened: The compiler yields the error:

error[E0277]: the trait bound `F: ~const Foo` is not satisfied
  --> file.rs:11:30
   |
11 |   const fn bat(f: F) -> u16 { f.bar() }
   |                               ^^^^^^^

Meta

This was tested on rustc 1.81.0-nightly (6b0f4b5 2024-06-24).

Activity

added
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Jun 26, 2024
added
A-diagnosticsArea: Messages for errors, warnings, and lints
F-effects`#![feature(effects)]`
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
and removed
C-bugCategory: This is a bug.
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Jun 26, 2024
fmease

fmease commented on Jun 26, 2024

@fmease
Member

The bound F: Foo in impl<F: Foo> Baz<F> { is non-const. You need to add a const-if-const bound F: ~const Foo ... to the method itself, not to the impl block (#119059, rust-lang/project-const-traits#11).

Once things are semi-working again, the code should look like the following (which won't necessarily be the final design):

#![feature(freeze, const_trait_impl)]

use std::marker::{Destruct, Freeze};

#[const_trait]
trait Foo {
    fn bar(&self) -> u16;
}

struct Baz<F: Foo>(F, u16);

impl<F: Foo> Baz<F> {
    const fn bat(f: F) -> u16
    where
        F: ~const Foo + ~const Destruct + Freeze,
    {
        f.bar()
    }
}
fmease

fmease commented on Jun 26, 2024

@fmease
Member

In the meantime, you could make it work by replacing ~const Destruct (from my snippet above) with Copy. That's more restrictive of course but at the time of writing Destruct is no longer a const trait while we're reworking things. This compiles and should work as expected:

#![feature(freeze, const_trait_impl)]

impl<F: Foo> Baz<F> {
    const fn bat(f: F) -> u16
    where
        F: ~const Foo + Copy + Freeze,
    {
        f.bar()
    }
}
added
D-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.
and removed
F-effects`#![feature(effects)]`
on Nov 15, 2024
changed the title [-]const Traits not being handled inside const associated functions/methods[/-] [+]Terse diagnostic on lack of ~const bound in inherent associated const functions[/+] on Nov 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsD-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.F-const_trait_impl`#![feature(const_trait_impl)]`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

        Participants

        @fmease@rustbot@alestane

        Issue actions

          Terse diagnostic on lack of ~const bound in inherent associated const functions · Issue #126975 · rust-lang/rust