Skip to content

Tracking issue for RFC 2526, "Support underscores as constant names" #54912

Closed
rust-lang/reference
#620

Description

@Centril

This is a tracking issue for the RFC "Support underscores as constant names" (rust-lang/rfcs#2526).

Steps:

Unresolved questions:

None

Activity

  1. added
    B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.
    T-langRelevant to the language team
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    on Oct 8, 2018
  2. petrochenkov commented on Oct 8, 2018

    @petrochenkov
    Contributor

    Ugh, seems like a legitimized hack rather than a... well, any of several proper features to which this can be generalized.

    At least this is a very tiny hack.
    Implementation strategy is the same as for use Trait as _;.
    If we encounter _ instead of the const name identifier, then we create a gensym for it instead of storing it in AST directly (so that different _s do not conflict).
    Together with a feature gate and tests that would be all the implementation.

  3. Centril commented on Oct 8, 2018

    @Centril
    ContributorAuthor

    Ugh, seems like a legitimized hack rather than a... well, any of several proper features to which this can be generalized.

    Hehe, I agree we should generalize (to patterns) eventually but it seemed that it was much more complex from @eddyb's comments. :)

  4. dsciarra commented on Oct 9, 2018

    @dsciarra
    Contributor

    looks interesting, I will give it a try!

  5. earthengine commented on Oct 11, 2018

    @earthengine

    @petrochenkov

    Can we also ensure that those gensyms get removed after before codegen? This means, the generated MIR should be removed in some MIR rounds.

  6. oli-obk commented on Oct 11, 2018

    @oli-obk
    Contributor

    We don't need to remove any MIR. Unused private constants don't end up in metadata.

  7. earthengine commented on Oct 12, 2018

    @earthengine

    @oli-obk

    Fine. There is one "inconsistency" in Rust today:

    let _: str = *"123"; //Legal
    let _v: str = *"123"; //Illegal unless unsized_rvalues

    When implementing this, how do we want to justify

    const _: str = *"123";
    const _v: str = *"123";

    Shall we repeat the inconsistency, or shall we count both valid or invalid?

  8. oli-obk commented on Oct 12, 2018

    @oli-obk
    Contributor

    I'd start out with both being disallowed, since that is the current behaviour of constants. But I have no strong opinion.

  9. added a commit that references this issue on Oct 14, 2018
  10. added
    B-unstableBlocker: Implemented in the nightly compiler and unstable.
    B-RFC-implementedBlocker: Approved by a merged RFC and implemented but not stabilized.
    on Oct 17, 2018
  11. Centril commented on Nov 11, 2018

    @Centril
    ContributorAuthor

    Setting earliest date for stabilization proposal to 25th november 2018 (14 days from now).

    We'll likely want to discuss what direction generalizations should go in before stabilizing.

  12. oli-obk commented on Nov 15, 2018

    @oli-obk
    Contributor

    The RFC did not discuss static _: T = ...;. Is that supposed to work, too? (the implementation does in fact allow this, accidentally even without a feature gate)

    Fix for the stability hole is in #55983

  13. 30 remaining items

  14. RalfJung commented on May 16, 2019

    @RalfJung
    Member

    let _ = is a weird beast, so the following sticks out from the RFC:

    Just like let _, this doesn't introduce any new bindings, but still evaluates the rvalue at compile time like any other constant.

    That's not "just like let _". let _ evaluates the place but never performs the place-to-rvalue coercion. Specifically, let _ = *v does not access memory, and let _ = mutex.lock().unwrap() does not drop the guard.

  15. earthengine commented on May 17, 2019

    @earthengine

    It is unfortunate that Rust was designed that way and we do not have a way back. It is really confusing to even experienced users unless they jump into the very deep level of the language.

    If this feature could ever be designed again, I would hope that let _ = ... to always performs the place-to-rvalue coercion unless it is no-op, so we have less weirdness.

    That's not "just like let _". let _ evaluates the place but never performs the place-to-rvalue coercion. Specifically, let _ = *v does not access memory, and let _ = mutex.lock().unwrap() does not drop the guard.

  16. nox commented on May 17, 2019

    @nox
    Contributor

    Specifically, let _ = *v does not access memory, and let _ = mutex.lock().unwrap() does not drop the guard.

    Did you mean that it does drop the guard?

    https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=94047cd4bd5f9e822ad19bdd55c15291

  17. RalfJung commented on May 17, 2019

    @RalfJung
    Member

    Dang, it got me again... this does not drop though:

    fn main() {
        let mutex = Mutex::new(());
        let val = mutex.lock().unwrap();
        let _ = val; // does not drop nor move.
        let _ = mutex.lock().unwrap();
    }
  18. eddyb commented on May 22, 2019

    @eddyb
    Contributor

    That's not "just like let _". let _ evaluates the place but never performs the place-to-rvalue coercion. Specifically, let _ = *v does not access memory, and let _ = mutex.lock().unwrap() does not drop the guard.

    I think the confusion here is the direction of the conversion. Matching against a pattern always does a "value to place" conversion, as patterns require places to do discriminant checks and field accesses, so:

    • let _ = place_expr; evaluates but doesn't access the place, so it's close to &raw place_expr
    • let _ = value_expr; evaluates the value, puts it in a temporary place, which gets dropped, so identical in behavior to drop(value_expr);, value_expr; or many other uses of a value expression where the value gets dropped - including &raw place_expr;!

    So depending on some exact details around unsafe code and whatnot, let _ = e; might be equivalent to &raw e; in all cases (ignoring optimizations, or assuming unused address-of are ignored).

  19. Centril commented on May 23, 2019

    @Centril
    ContributorAuthor

    If the _ is interpreted as a pattern, and not as a unique identifier like in use foo as _;, then the implementation needs to be changed to not add the names of _ consts into their parent modules.

    I think it would be good to fix this so that we treat const _: T = expr; as we do with extern { .. } and foo!(); in an item position right now. That is, it doesn't have a name, and we don't gensym. That might perhaps involve having Option<Ident> in the hir::Item.

  20. eddyb commented on May 24, 2019

    @eddyb
    Contributor

    You don't need Option because extern {...} and foo!(); already work with ident: Ident in {ast,hir}::Item (via the "Invalid" "keyword", aka Symbol::intern("")).

  21. Centril commented on May 29, 2019

    @Centril
    ContributorAuthor

    @petrochenkov Are there any observable differences between _ as PatKind::Wild and using gensyms as it is implemented right now (aside from rustdoc which isn't important here) such that it matters wrt. stability and forward compatibility?

  22. petrochenkov commented on May 29, 2019

    @petrochenkov
    Contributor

    Are there any observable differences between _ as PatKind::Wild and using gensyms as it is implemented right now

    No, there should be no observable difference after #56392.
    They just create some extra work for the resolver and also encoder/decoder, I think.

  23. Centril commented on May 30, 2019

    @Centril
    ContributorAuthor

    We discussed this on the language team meeting today and gave the green light for a stabilization report and PR (see above). I will be writing the report and adding it to the PR within a few hours.

  24. added a commit that references this issue on Sep 15, 2019
  25. added a commit that references this issue on Jan 6, 2020
  26. added a commit that references this issue on Jan 7, 2020
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

    B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.B-RFC-implementedBlocker: Approved by a merged RFC and implemented but not stabilized.B-unstableBlocker: Implemented in the nightly compiler and unstable.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCT-langRelevant to the language team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions