Skip to content

unused function is not monomorphized, so post-mono lints do not show up (in particular affects associated and inline consts) #106617

Closed

Description

@zirconium-n

I tried this code:

#![feature(inline_const)]

fn run() {
    const { assert!(false) };
}

I expected to see this happen: compile error.

Instead, this happened: compile passes.

If I change the visibility of fn run to pub, it will throw a compile error.

For comparison, const value always throw a compile error even if the const is never used.

const X: i32 = {
    assert!(false);   // This will error!
    1
};

Activity

  1. scottmcm commented on Jan 9, 2023

    @scottmcm
    Member

    Hi lang (and maybe @RalfJung)! I'll miss the meeting on Tuesday, but I figured I'd nominate this since the feature is in FCP now, and this looks breaking to fix.

    Do we expect that inline consts in non-generic unused private functions aren't evaluated?

  2. nbdd0121 commented on Jan 9, 2023

    @nbdd0121
    Member

    This is intentional, as the same behaviour is true for associated consts.

    fn run() {
        struct Foo;
        impl Foo {
            const A: () = assert!(false);
        }
        Foo::A
    }

    The use is not collected and evaluated if not monomorphized.

  3. zirconium-n commented on Jan 9, 2023

    @zirconium-n
    ContributorAuthor

    This is intentional, as the same behaviour is true for associated consts.

    fn run() {
        struct Foo;
        impl Foo {
            const A: () = assert!(false);
        }
        Foo::A
    }

    The use is not collected and evaluated if not monomorphized.

    Actually I won't expect this would compile either. 😕

    Are you sure this is intentional, instead of some accidental behavior?

  4. nbdd0121 commented on Jan 9, 2023

    @nbdd0121
    Member

    It's documented that they are not evaluated if not used, and generic associated consts are evaluated at mono (https://doc.rust-lang.org/beta/reference/items/associated-items.html#associated-constants).

    It's not documented when a non-generic associated will evaluated, but it sounds rather inconsistent if it's not also evaluated at monomorphization time.

  5. zirconium-n commented on Jan 9, 2023

    @zirconium-n
    ContributorAuthor

    It's documented that they are not evaluated if not used, and generic associated consts are evaluated at mono (https://doc.rust-lang.org/beta/reference/items/associated-items.html#associated-constants).

    It's not documented when a non-generic associated will evaluated, but it sounds rather inconsistent if it's not also evaluated at monomorphization time.

    Learning something new every day, really.

    But back to my case, I think my code in OP translate to

    fn run() {
        const _: () = assert!(false);
    }

    which throws a compile time error.

  6. nbdd0121 commented on Jan 9, 2023

    @nbdd0121
    Member

    No, const blocks are handled similar to associated consts as opposed to const items. The latter cannot use generics.

  7. RalfJung commented on Jan 9, 2023

    @RalfJung
    Member

    The problem is that could can write code like this

    fn run<T>() {
        const { assert!(std::mem::size_of::<T>() > 0) };
    }

    Asking to evaluate inline consts in an unused generic function is meaningless, since we can't know the generic parameters.

    We could in principle add a special case that applies only to monomorphic functions like your original example. That would not have any direct relation to inline consts though, it affects associated consts just as much.

  8. zirconium-n commented on Jan 11, 2023

    @zirconium-n
    ContributorAuthor

    The problem is that could can write code like this

    fn run<T>() {
        const { assert!(std::mem::size_of::<T>() > 0) };
    }

    Asking to evaluate inline consts in an unused generic function is meaningless, since we can't know the generic parameters.

    Yes, I agree this is meaningless.

    We could in principle add a special case that applies only to monomorphic functions like your original example. That would not have any direct relation to inline consts though, it affects associated consts just as much.

    @nbdd0121 gave a pretty good reason why it's handled like this. It's the combined behavior surprised me, but it's understandable.

    I'm ok with either way, compile or not. Actually I would prefer less special cases (if we consider it one).

  9. nbdd0121 commented on Jan 11, 2023

    @nbdd0121
    Member

    There is a -C link-dead-code option to force non-generic functions being monomorphized.

  10. lukas-code commented on Feb 9, 2023

    @lukas-code
    Contributor

    For what it's worth, the behavior of inline_const here matches overflowing generics: playground

    pub const fn overflow(x: impl Sized) {
        overflow((x,))
    }
    
    fn ok() {
        overflow(())
    }
    
    pub fn error() {
        overflow(())
    }
  11. tmandry commented on Feb 14, 2023

    @tmandry
    Member

    Deferring discussion for now to the design meeting in rust-lang/lang-team#195.

    @rustbot label: -I-lang-nominated

  12. removed
    I-lang-nominatedNominated for discussion during a lang team meeting.
    on Feb 14, 2023
  13. added
    F-inline_constInline constants (aka: const blocks, const expressions, anonymous constants)
    on Mar 5, 2023
  14. changed the title [-]inline_const does not evaluate in unused function[/-] [+]unused function is not monomorphized, so post-mono lints only show up in debug builds (in particular affects associated and inline consts)[/+] on May 17, 2023
  15. changed the title [-]unused function is not monomorphized, so post-mono lints only show up in debug builds (in particular affects associated and inline consts)[/-] [+]unused function is not monomorphized, so post-mono lints do not show up (in particular affects associated and inline consts)[/+] on May 17, 2023
  16. RalfJung commented on May 25, 2023

    @RalfJung
    Member

    Closing in favor of #107503 which is basically the same underlying issue.

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-monomorphizationArea: MonomorphizationC-bugCategory: This is a bug.F-inline_constInline constants (aka: const blocks, const expressions, anonymous constants)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions