Skip to content

Tracking Issue for infallible promotion #80619

Closed

Description

@RalfJung

This is a tracking issue for the RFC "3027" (rust-lang/rfcs#3027).
The RFC does not have a feature gate.

About tracking issues

Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.

Steps

Unresolved Questions

Implementation history

Activity

  1. added
    T-langRelevant to the language team
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)
    on Jan 2, 2021
  2. RalfJung commented on Jan 2, 2021

    @RalfJung
    MemberAuthor

    In #80243 we learned that there is at least some code (e.g. rodrimati1992/abi_stable_crates#46) that relies in non-trivial ways on const fn calls being promoted in a const/static initializer. We need to figure out how to move forward with such code. I see these options:

    • Live with the fact that promoteds in const/static initializers can fail even if they are not required for said initializer. This means no breaking change here, but it will require care in MIR optimizations, MIR printing, maybe more.
    • Make sure that all potentally-failing promoteds in const/static initializers are required to compute the value of the const. This will require some break change. There are different alternatives here:
      • Never promote anything that might fail -- this breaks some real code (no idea how much, it's only 2 crates in crater), but leads to a rather clean situation.
      • Only promote things that fail if they are in parts of the CFG that will definitely be evaluated -- that will however be rather surprising behavior, so maybe we want to do this only for old editions. In particular, a proper post-dominance analysis might be too expensive, so we might just check if the entire CFG is linear, or we only promote on the "linear head" of the CFG; in either case, adding a conditional somewhere in the code will stop promotion of things further down that code, which is rather odd.
  3. Aaron1011 commented on Jan 2, 2021

    @Aaron1011
    Contributor

    Never promote anything that might fail -- this breaks some real code (no idea how much, it's only 2 crates in crater), but leads to a rather clean situation.

    Can that code be made to compile with inline const blocks?

  4. RalfJung commented on Jan 2, 2021

    @RalfJung
    MemberAuthor

    @Aaron1011 yes it can, but only once inline const blocks can use generics of the surrounding context.

  5. changed the title [-]Tracking Issue for infallibe promotion[/-] [+]Tracking Issue for infallible promotion[/+] on Feb 14, 2021
  6. RalfJung commented on May 9, 2021

    @RalfJung
    MemberAuthor

    I think this is probably the best option:

    Live with the fact that promoteds in const/static initializers can fail even if they are not required for said initializer. This means no breaking change here, but it will require care in MIR optimizations, MIR printing, maybe more.

    #85112 ensures that at least a normal build handles this correctly. @oli-obk any idea how to check other MIR consumers such as MIR printing for this?

  7. oli-obk commented on May 9, 2021

    @oli-obk
    Contributor

    MIR printing should just print the path to unevaluated constants and not eval them at all. The only other thing would be optimizations, but these aren't run for constants' bodies

  8. RalfJung commented on May 12, 2021

    @RalfJung
    MemberAuthor

    MIR printing should just print the path to unevaluated constants and not eval them at all.

    As in, it already does that, or it should be changed to do that?

  9. oli-obk commented on May 12, 2021

    @oli-obk
    Contributor

    I believe it does that. At least I specifically remember seeing paths being printed for things that could have been evaluated.

  10. RalfJung commented on May 15, 2021

    @RalfJung
    MemberAuthor

    If we end up deciding we are okay with promoting const fn calls in const/static bodies, we might then also accept other things like general array indexing or division -- we could accept basically everything that qualifies syntactically, i.e., anything that does not depend on surrounding variables. I am not sure what is the better choice -- this makes the rules even more inconsistent, but the rules already are wildly inconsistent to the extend that people do get confused by it (e.g., #85181).

  11. added
    S-tracking-needs-summaryStatus: It's hard to tell what's been done and what hasn't! Someone should do some investigation.
    on Jul 20, 2022
  12. joshtriplett commented on Jul 20, 2022

    @joshtriplett
    Member

    What items from RFC 3027 remain to be implemented?

    We talked about this in today's @rust-lang/lang meeting, and we know that const { ... } still needs further implementation, but we weren't sure if that was a blocker for this or if all the work specified by the RFC was complete.

  13. RalfJung commented on Jul 20, 2022

    @RalfJung
    MemberAuthor

    @joshtriplett the main open question is what is listed as unresolved question in the issue:

    What should we do about promoting const fn calls in const/static initializers? See this crater analysis and this Zulip thread.

    Basically we still promote arbitrary function calls inside const/static initializers. We need to decide whether we want to

    • Live with this technical debt
    • Try to slowly phase it out in favor of const blocks (once those are stable)

    This is a MIR building thing so it could potentially be done at an edition boundary. However, as long as any edition promotes arbitrary fn calls, MIR optimizations need to be careful and not overeagerly evaluate constants they find to determine their value. So the technical debt does not become any better by making this an edition thing. I am not sure whether doing this only for the sake of "rules of the latest edition are easier to explain" is worth it.

  14. 16 remaining items

  15. added 9 commits that reference this issue on Mar 12, 2024
  16. RalfJung commented on Mar 21, 2024

    @RalfJung
    MemberAuthor

    Regarding the chance to entirely get rid of promotion of function calls -- currently, that breaks the build of cargo, due to this constant in time:

    const UTC_OFFSET_FORMAT: &[FormatItem<'_>] = &[
        FormatItem::Component(Component::OffsetHour({
            let mut m = modifier::OffsetHour::default();
            m.sign_is_mandatory = true;
            m
        })),
        FormatItem::Optional(&FormatItem::Compound(&[
            FormatItem::Literal(b":"),
            FormatItem::Component(Component::OffsetMinute(modifier::OffsetMinute::default())),
            FormatItem::Optional(&FormatItem::Compound(&[
                FormatItem::Literal(b":"),
                FormatItem::Component(Component::OffsetSecond(modifier::OffsetSecond::default())),
            ])),
        ])),
    ];

    The default() calls here are function calls which are being promoted.

    This could easily be fixed by using associated consts instead of functions. But who knows what we'd run into next...

  17. added a commit that references this issue on Mar 23, 2024
  18. added 2 commits that reference this issue on Apr 23, 2024
  19. RalfJung commented on Apr 24, 2024

    @RalfJung
    MemberAuthor

    #121557 landed. So we have finally achieved Elysium the property that all potentially failing consts are captured by required_consts. :)

    I think we can consider the RFC to be fully implemented now. 🎉
    I have opened #124328 to track cleaning up the "hacks" we had to add to get here.

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-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCS-tracking-needs-summaryStatus: It's hard to tell what's been done and what hasn't! Someone should do some investigation.T-langRelevant to the language team

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions