Skip to content

Parsable associated enum constructor #79658

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
iunof opened this issue Dec 3, 2020 · 6 comments · Fixed by #80080
Closed

Parsable associated enum constructor #79658

iunof opened this issue Dec 3, 2020 · 6 comments · Fixed by #80080
Assignees
Labels
A-parser Area: The lexing & parsing of Rust source code to an AST C-bug Category: This is a bug. P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@iunof
Copy link

iunof commented Dec 3, 2020

I tried this code:

fn main() {
    {
        type Enum = <Bar as A>::Assoc;
        let bar = Enum::Bar(9);
        let foo = Enum::Foo{br: 3};
    }
    {
        let bar = <Bar as A>::Assoc::Bar(9);
        let foo = <Bar as A>::Assoc::Foo{br: 3};
    }

}

trait A {
    type Assoc;
}

enum Foo {
    Foo {br: i8},
    Bar(u8),
}

struct Bar;

impl A for Bar {
    type Assoc = Foo;
}

I expected to see this happen: in second block foo = Foo::Foo {br: 3}

Instead, this happened: compilation error

error: expected one of `.`, `::`, `;`, `?`, or an operator, found `{`
 --> src/main.rs:9:41
  |
9 |         let foo = <Bar as A>::Assoc::Foo{br: 3};
  |                                         ^ expected one of `.`, `::`, `;`, `?`, or an operator

error: aborting due to previous error

Playground

Meta

Stable channel 1.48.0
Beta channel 1.49.0-beta.2 (2020-11-24 bd26e4e544992e52f208)
Nightly channel 1.50.0-nightly (2020-11-30 b7ebc6b0c1ba3c27ebb1)
@iunof iunof added the C-bug Category: This is a bug. label Dec 3, 2020
@camelid camelid added A-parser Area: The lexing & parsing of Rust source code to an AST I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Dec 4, 2020
@rylev
Copy link
Member

rylev commented Dec 4, 2020

@rustbot claim

@camelid camelid added T-lang Relevant to the language team, which will review and decide on the PR/issue. I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 4, 2020
@camelid
Copy link
Member

camelid commented Dec 4, 2020

Nominating for T-lang T-compiler: is this intended language design or was it an oversight when implementing the parser?

@petrochenkov
Copy link
Contributor

It's intended in the sense that qualified paths <Foo as Bar>::Baz are so useless in

  • struct expression,
  • struct pattern, and
  • tuple struct pattern

contexts that nobody ever bothered implementing them.

Name resolution and type checking support for associated items in these positions was implemented in late 2016 (#37035), starting from that point the surface syntax for qualified paths could be added at any point.

I guess they can be supported now for consistency.

@rylev
Copy link
Member

rylev commented Dec 8, 2020

Since I'm new to the parser, I did some investigation on what the issue is.

When parsing the expression <Bar as A>::Assoc::Foo { br: 3 }, parse_bottom_expr is called. This looks ahead at a bunch of tokens eventually seeing < which leads the parser to attempt to parse this as a QPath. parse_qpath only returns QSelf (Bar in this case) as well as the path A::Assoc::Foo but nothing more. parse_qpath takes a PathStyle for parsing qpaths in different contexts including type position and expression position.

The solution is probably to change parse_qpath to try to parse struct and enums as part of the qpath parsing when PathStyle is PathStyle::Expr. I believe when parsing regular paths, parse_path_start_expr is called which internally calls maybe_parse_struct_expr. Perhaps we want to do something similar. The issue is that structs don't have a place to store a QSelf so we should probably start by changing ExprKind::Struct to take an optional QSelf.

@petrochenkov
Copy link
Contributor

The issue is that structs don't have a place to store a QSelf so we should probably start by changing ExprKind::Struct to take an optional QSelf.

Yes, that's the main thing.
ExprKind::Struct, PatKind::Struct and PatKind::TupleStruct needs to get a QSelf field to be able to pass qualified paths further.

Then errors need to be removed from fn parse_pat_struct and fn parse_pat_tuple_struct + path and qpath branches in fn parse_bottom_expr need to be merged.

@apiraino
Copy link
Contributor

Assigning P-medium as discussed as part of the Prioritization Working Group procedure and removing I-prioritize.

@apiraino apiraino added P-medium Medium priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Dec 16, 2020
@bors bors closed this as completed in 16e1839 Jun 10, 2021
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-parser Area: The lexing & parsing of Rust source code to an AST C-bug Category: This is a bug. P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants