From 50a02eb3593591a02677e1b56f24d7ff0459b9d0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 12 Aug 2020 17:06:49 +0200 Subject: Rename ra_parser -> parser --- crates/parser/src/grammar/items/adt.rs | 178 ++++++++++++++++++++++++++++ crates/parser/src/grammar/items/consts.rs | 33 ++++++ crates/parser/src/grammar/items/traits.rs | 153 ++++++++++++++++++++++++ crates/parser/src/grammar/items/use_item.rs | 132 +++++++++++++++++++++ 4 files changed, 496 insertions(+) create mode 100644 crates/parser/src/grammar/items/adt.rs create mode 100644 crates/parser/src/grammar/items/consts.rs create mode 100644 crates/parser/src/grammar/items/traits.rs create mode 100644 crates/parser/src/grammar/items/use_item.rs (limited to 'crates/parser/src/grammar/items') diff --git a/crates/parser/src/grammar/items/adt.rs b/crates/parser/src/grammar/items/adt.rs new file mode 100644 index 000000000..addfb59d4 --- /dev/null +++ b/crates/parser/src/grammar/items/adt.rs @@ -0,0 +1,178 @@ +//! FIXME: write short doc here + +use super::*; + +pub(super) fn struct_def(p: &mut Parser, m: Marker) { + assert!(p.at(T![struct])); + p.bump(T![struct]); + struct_or_union(p, m, T![struct], STRUCT); +} + +pub(super) fn union_def(p: &mut Parser, m: Marker) { + assert!(p.at_contextual_kw("union")); + p.bump_remap(T![union]); + struct_or_union(p, m, T![union], UNION); +} + +fn struct_or_union(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { + name_r(p, ITEM_RECOVERY_SET); + type_params::opt_type_param_list(p); + match p.current() { + T![where] => { + type_params::opt_where_clause(p); + match p.current() { + T![;] => { + p.bump(T![;]); + } + T!['{'] => record_field_def_list(p), + _ => { + //FIXME: special case `(` error message + p.error("expected `;` or `{`"); + } + } + } + T![;] if kw == T![struct] => { + p.bump(T![;]); + } + T!['{'] => record_field_def_list(p), + T!['('] if kw == T![struct] => { + tuple_field_def_list(p); + // test tuple_struct_where + // struct Test(T) where T: Clone; + // struct Test(T); + type_params::opt_where_clause(p); + p.expect(T![;]); + } + _ if kw == T![struct] => { + p.error("expected `;`, `{`, or `(`"); + } + _ => { + p.error("expected `{`"); + } + } + m.complete(p, def); +} + +pub(super) fn enum_def(p: &mut Parser, m: Marker) { + assert!(p.at(T![enum])); + p.bump(T![enum]); + name_r(p, ITEM_RECOVERY_SET); + type_params::opt_type_param_list(p); + type_params::opt_where_clause(p); + if p.at(T!['{']) { + enum_variant_list(p); + } else { + p.error("expected `{`") + } + m.complete(p, ENUM); +} + +pub(crate) fn enum_variant_list(p: &mut Parser) { + assert!(p.at(T!['{'])); + let m = p.start(); + p.bump(T!['{']); + while !p.at(EOF) && !p.at(T!['}']) { + if p.at(T!['{']) { + error_block(p, "expected enum variant"); + continue; + } + let var = p.start(); + attributes::outer_attributes(p); + if p.at(IDENT) { + name(p); + match p.current() { + T!['{'] => record_field_def_list(p), + T!['('] => tuple_field_def_list(p), + _ => (), + } + + // test variant_discriminant + // enum E { X(i32) = 10 } + if p.eat(T![=]) { + expressions::expr(p); + } + var.complete(p, VARIANT); + } else { + var.abandon(p); + p.err_and_bump("expected enum variant"); + } + if !p.at(T!['}']) { + p.expect(T![,]); + } + } + p.expect(T!['}']); + m.complete(p, VARIANT_LIST); +} + +pub(crate) fn record_field_def_list(p: &mut Parser) { + assert!(p.at(T!['{'])); + let m = p.start(); + p.bump(T!['{']); + while !p.at(T!['}']) && !p.at(EOF) { + if p.at(T!['{']) { + error_block(p, "expected field"); + continue; + } + record_field_def(p); + if !p.at(T!['}']) { + p.expect(T![,]); + } + } + p.expect(T!['}']); + m.complete(p, RECORD_FIELD_LIST); + + fn record_field_def(p: &mut Parser) { + let m = p.start(); + // test record_field_attrs + // struct S { + // #[serde(with = "url_serde")] + // pub uri: Uri, + // } + attributes::outer_attributes(p); + opt_visibility(p); + if p.at(IDENT) { + name(p); + p.expect(T![:]); + types::type_(p); + m.complete(p, RECORD_FIELD); + } else { + m.abandon(p); + p.err_and_bump("expected field declaration"); + } + } +} + +fn tuple_field_def_list(p: &mut Parser) { + assert!(p.at(T!['('])); + let m = p.start(); + if !p.expect(T!['(']) { + return; + } + while !p.at(T![')']) && !p.at(EOF) { + let m = p.start(); + // test tuple_field_attrs + // struct S ( + // #[serde(with = "url_serde")] + // pub Uri, + // ); + // + // enum S { + // Uri(#[serde(with = "url_serde")] Uri), + // } + attributes::outer_attributes(p); + opt_visibility(p); + if !p.at_ts(types::TYPE_FIRST) { + p.error("expected a type"); + m.complete(p, ERROR); + break; + } + types::type_(p); + m.complete(p, TUPLE_FIELD); + + if !p.at(T![')']) { + p.expect(T![,]); + } + } + p.expect(T![')']); + m.complete(p, TUPLE_FIELD_LIST); +} diff --git a/crates/parser/src/grammar/items/consts.rs b/crates/parser/src/grammar/items/consts.rs new file mode 100644 index 000000000..35ad766dc --- /dev/null +++ b/crates/parser/src/grammar/items/consts.rs @@ -0,0 +1,33 @@ +//! FIXME: write short doc here + +use super::*; + +pub(super) fn static_def(p: &mut Parser, m: Marker) { + const_or_static(p, m, T![static], STATIC) +} + +pub(super) fn const_def(p: &mut Parser, m: Marker) { + const_or_static(p, m, T![const], CONST) +} + +fn const_or_static(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { + assert!(p.at(kw)); + p.bump(kw); + p.eat(T![mut]); // FIXME: validator to forbid const mut + + // Allow `_` in place of an identifier in a `const`. + let is_const_underscore = kw == T![const] && p.eat(T![_]); + if !is_const_underscore { + name(p); + } + + // test_err static_underscore + // static _: i32 = 5; + + types::ascription(p); + if p.eat(T![=]) { + expressions::expr(p); + } + p.expect(T![;]); + m.complete(p, def); +} diff --git a/crates/parser/src/grammar/items/traits.rs b/crates/parser/src/grammar/items/traits.rs new file mode 100644 index 000000000..751ce65f2 --- /dev/null +++ b/crates/parser/src/grammar/items/traits.rs @@ -0,0 +1,153 @@ +//! FIXME: write short doc here + +use super::*; + +// test trait_item +// trait T: Hash + Clone where U: Copy {} +// trait X: Hash + Clone where U: Copy {} +pub(super) fn trait_def(p: &mut Parser) { + assert!(p.at(T![trait])); + p.bump(T![trait]); + name_r(p, ITEM_RECOVERY_SET); + type_params::opt_type_param_list(p); + // test trait_alias + // trait Z = T; + // trait Z = T where U: Copy; + // trait Z = where Self: T; + if p.eat(T![=]) { + type_params::bounds_without_colon(p); + type_params::opt_where_clause(p); + p.expect(T![;]); + return; + } + if p.at(T![:]) { + type_params::bounds(p); + } + type_params::opt_where_clause(p); + if p.at(T!['{']) { + trait_item_list(p); + } else { + p.error("expected `{`"); + } +} + +// test trait_item_list +// impl F { +// type A: Clone; +// const B: i32; +// fn foo() {} +// fn bar(&self); +// } +pub(crate) fn trait_item_list(p: &mut Parser) { + assert!(p.at(T!['{'])); + let m = p.start(); + p.bump(T!['{']); + while !p.at(EOF) && !p.at(T!['}']) { + if p.at(T!['{']) { + error_block(p, "expected an item"); + continue; + } + item_or_macro(p, true); + } + p.expect(T!['}']); + m.complete(p, ASSOC_ITEM_LIST); +} + +// test impl_def +// impl Foo {} +pub(super) fn impl_def(p: &mut Parser) { + assert!(p.at(T![impl])); + p.bump(T![impl]); + if choose_type_params_over_qpath(p) { + type_params::opt_type_param_list(p); + } + + // FIXME: never type + // impl ! {} + + // test impl_def_neg + // impl !Send for X {} + p.eat(T![!]); + impl_type(p); + if p.eat(T![for]) { + impl_type(p); + } + type_params::opt_where_clause(p); + if p.at(T!['{']) { + impl_item_list(p); + } else { + p.error("expected `{`"); + } +} + +// test impl_item_list +// impl F { +// type A = i32; +// const B: i32 = 92; +// fn foo() {} +// fn bar(&self) {} +// } +pub(crate) fn impl_item_list(p: &mut Parser) { + assert!(p.at(T!['{'])); + let m = p.start(); + p.bump(T!['{']); + // test impl_inner_attributes + // enum F{} + // impl F { + // //! This is a doc comment + // #![doc("This is also a doc comment")] + // } + attributes::inner_attributes(p); + + while !p.at(EOF) && !p.at(T!['}']) { + if p.at(T!['{']) { + error_block(p, "expected an item"); + continue; + } + item_or_macro(p, true); + } + p.expect(T!['}']); + m.complete(p, ASSOC_ITEM_LIST); +} + +// test impl_type_params +// impl Bar {} +fn choose_type_params_over_qpath(p: &Parser) -> bool { + // There's an ambiguity between generic parameters and qualified paths in impls. + // If we see `<` it may start both, so we have to inspect some following tokens. + // The following combinations can only start generics, + // but not qualified paths (with one exception): + // `<` `>` - empty generic parameters + // `<` `#` - generic parameters with attributes + // `<` `const` - const generic parameters + // `<` (LIFETIME|IDENT) `>` - single generic parameter + // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list + // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds + // `<` (LIFETIME|IDENT) `=` - generic parameter with a default + // The only truly ambiguous case is + // `<` IDENT `>` `::` IDENT ... + // we disambiguate it in favor of generics (`impl ::absolute::Path { ... }`) + // because this is what almost always expected in practice, qualified paths in impls + // (`impl ::AssocTy { ... }`) aren't even allowed by type checker at the moment. + if !p.at(T![<]) { + return false; + } + if p.nth(1) == T![#] || p.nth(1) == T![>] || p.nth(1) == CONST_KW { + return true; + } + (p.nth(1) == LIFETIME || p.nth(1) == IDENT) + && (p.nth(2) == T![>] || p.nth(2) == T![,] || p.nth(2) == T![:] || p.nth(2) == T![=]) +} + +// test_err impl_type +// impl Type {} +// impl Trait1 for T {} +// impl impl NotType {} +// impl Trait2 for impl NotType {} +pub(crate) fn impl_type(p: &mut Parser) { + if p.at(T![impl]) { + p.error("expected trait or type"); + return; + } + types::type_(p); +} diff --git a/crates/parser/src/grammar/items/use_item.rs b/crates/parser/src/grammar/items/use_item.rs new file mode 100644 index 000000000..8e836a77e --- /dev/null +++ b/crates/parser/src/grammar/items/use_item.rs @@ -0,0 +1,132 @@ +//! FIXME: write short doc here + +use super::*; + +pub(super) fn use_item(p: &mut Parser, m: Marker) { + assert!(p.at(T![use])); + p.bump(T![use]); + use_tree(p, true); + p.expect(T![;]); + m.complete(p, USE); +} + +/// Parse a use 'tree', such as `some::path` in `use some::path;` +/// Note that this is called both by `use_item` and `use_tree_list`, +/// so handles both `some::path::{inner::path}` and `inner::path` in +/// `use some::path::{inner::path};` +fn use_tree(p: &mut Parser, top_level: bool) { + let m = p.start(); + match p.current() { + // Finish the use_tree for cases of e.g. + // `use some::path::{self, *};` or `use *;` + // This does not handle cases such as `use some::path::*` + // N.B. in Rust 2015 `use *;` imports all from crate root + // however in Rust 2018 `use *;` errors: ('cannot glob-import all possible crates') + // FIXME: Add this error (if not out of scope) + + // test use_star + // use *; + // use ::*; + // use some::path::{*}; + // use some::path::{::*}; + T![*] => p.bump(T![*]), + T![:] if p.at(T![::]) && p.nth(2) == T![*] => { + // Parse `use ::*;`, which imports all from the crate root in Rust 2015 + // This is invalid inside a use_tree_list, (e.g. `use some::path::{::*}`) + // but still parses and errors later: ('crate root in paths can only be used in start position') + // FIXME: Add this error (if not out of scope) + // In Rust 2018, it is always invalid (see above) + p.bump(T![::]); + p.bump(T![*]); + } + // Open a use tree list + // Handles cases such as `use {some::path};` or `{inner::path}` in + // `use some::path::{{inner::path}, other::path}` + + // test use_tree_list + // use {crate::path::from::root, or::path::from::crate_name}; // Rust 2018 (with a crate named `or`) + // use {path::from::root}; // Rust 2015 + // use ::{some::arbritrary::path}; // Rust 2015 + // use ::{{{root::export}}}; // Nonsensical but perfectly legal nesting + T!['{'] => { + use_tree_list(p); + } + T![:] if p.at(T![::]) && p.nth(2) == T!['{'] => { + p.bump(T![::]); + use_tree_list(p); + } + // Parse a 'standard' path. + // Also handles aliases (e.g. `use something as something_else`) + + // test use_path + // use ::crate_name; // Rust 2018 - All flavours + // use crate_name; // Rust 2018 - Anchored paths + // use item_in_scope_or_crate_name; // Rust 2018 - Uniform Paths + // + // use self::module::Item; + // use crate::Item; + // use self::some::Struct; + // use crate_name::some_item; + _ if paths::is_use_path_start(p) => { + paths::use_path(p); + match p.current() { + T![as] => { + // test use_alias + // use some::path as some_name; + // use some::{ + // other::path as some_other_name, + // different::path as different_name, + // yet::another::path, + // running::out::of::synonyms::for_::different::* + // }; + // use Trait as _; + opt_alias(p); + } + T![:] if p.at(T![::]) => { + p.bump(T![::]); + match p.current() { + T![*] => { + p.bump(T![*]); + } + // test use_tree_list_after_path + // use crate::{Item}; + // use self::{Item}; + T!['{'] => use_tree_list(p), + _ => { + // is this unreachable? + p.error("expected `{` or `*`"); + } + } + } + _ => (), + } + } + _ => { + m.abandon(p); + let msg = "expected one of `*`, `::`, `{`, `self`, `super` or an identifier"; + if top_level { + p.err_recover(msg, ITEM_RECOVERY_SET); + } else { + // if we are parsing a nested tree, we have to eat a token to + // main balanced `{}` + p.err_and_bump(msg); + } + return; + } + } + m.complete(p, USE_TREE); +} + +pub(crate) fn use_tree_list(p: &mut Parser) { + assert!(p.at(T!['{'])); + let m = p.start(); + p.bump(T!['{']); + while !p.at(EOF) && !p.at(T!['}']) { + use_tree(p, false); + if !p.at(T!['}']) { + p.expect(T![,]); + } + } + p.expect(T!['}']); + m.complete(p, USE_TREE_LIST); +} -- cgit v1.2.3 From 6bc2633c90cedad057c5201d1ab7f67b57247004 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 13 Aug 2020 17:58:35 +0200 Subject: Align parser names with grammar --- crates/parser/src/grammar/items/adt.rs | 34 +++++++++++++------------- crates/parser/src/grammar/items/consts.rs | 4 +-- crates/parser/src/grammar/items/traits.rs | 38 ++++++----------------------- crates/parser/src/grammar/items/use_item.rs | 4 +-- 4 files changed, 29 insertions(+), 51 deletions(-) (limited to 'crates/parser/src/grammar/items') diff --git a/crates/parser/src/grammar/items/adt.rs b/crates/parser/src/grammar/items/adt.rs index addfb59d4..67c0c5697 100644 --- a/crates/parser/src/grammar/items/adt.rs +++ b/crates/parser/src/grammar/items/adt.rs @@ -2,13 +2,13 @@ use super::*; -pub(super) fn struct_def(p: &mut Parser, m: Marker) { +pub(super) fn strukt(p: &mut Parser, m: Marker) { assert!(p.at(T![struct])); p.bump(T![struct]); struct_or_union(p, m, T![struct], STRUCT); } -pub(super) fn union_def(p: &mut Parser, m: Marker) { +pub(super) fn union(p: &mut Parser, m: Marker) { assert!(p.at_contextual_kw("union")); p.bump_remap(T![union]); struct_or_union(p, m, T![union], UNION); @@ -16,7 +16,7 @@ pub(super) fn union_def(p: &mut Parser, m: Marker) { fn struct_or_union(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { name_r(p, ITEM_RECOVERY_SET); - type_params::opt_type_param_list(p); + type_params::opt_generic_param_list(p); match p.current() { T![where] => { type_params::opt_where_clause(p); @@ -24,7 +24,7 @@ fn struct_or_union(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { T![;] => { p.bump(T![;]); } - T!['{'] => record_field_def_list(p), + T!['{'] => record_field_list(p), _ => { //FIXME: special case `(` error message p.error("expected `;` or `{`"); @@ -34,9 +34,9 @@ fn struct_or_union(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { T![;] if kw == T![struct] => { p.bump(T![;]); } - T!['{'] => record_field_def_list(p), + T!['{'] => record_field_list(p), T!['('] if kw == T![struct] => { - tuple_field_def_list(p); + tuple_field_list(p); // test tuple_struct_where // struct Test(T) where T: Clone; // struct Test(T); @@ -53,21 +53,21 @@ fn struct_or_union(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { m.complete(p, def); } -pub(super) fn enum_def(p: &mut Parser, m: Marker) { +pub(super) fn enum_(p: &mut Parser, m: Marker) { assert!(p.at(T![enum])); p.bump(T![enum]); name_r(p, ITEM_RECOVERY_SET); - type_params::opt_type_param_list(p); + type_params::opt_generic_param_list(p); type_params::opt_where_clause(p); if p.at(T!['{']) { - enum_variant_list(p); + variant_list(p); } else { p.error("expected `{`") } m.complete(p, ENUM); } -pub(crate) fn enum_variant_list(p: &mut Parser) { +pub(crate) fn variant_list(p: &mut Parser) { assert!(p.at(T!['{'])); let m = p.start(); p.bump(T!['{']); @@ -77,12 +77,12 @@ pub(crate) fn enum_variant_list(p: &mut Parser) { continue; } let var = p.start(); - attributes::outer_attributes(p); + attributes::outer_attrs(p); if p.at(IDENT) { name(p); match p.current() { - T!['{'] => record_field_def_list(p), - T!['('] => tuple_field_def_list(p), + T!['{'] => record_field_list(p), + T!['('] => tuple_field_list(p), _ => (), } @@ -104,7 +104,7 @@ pub(crate) fn enum_variant_list(p: &mut Parser) { m.complete(p, VARIANT_LIST); } -pub(crate) fn record_field_def_list(p: &mut Parser) { +pub(crate) fn record_field_list(p: &mut Parser) { assert!(p.at(T!['{'])); let m = p.start(); p.bump(T!['{']); @@ -128,7 +128,7 @@ pub(crate) fn record_field_def_list(p: &mut Parser) { // #[serde(with = "url_serde")] // pub uri: Uri, // } - attributes::outer_attributes(p); + attributes::outer_attrs(p); opt_visibility(p); if p.at(IDENT) { name(p); @@ -142,7 +142,7 @@ pub(crate) fn record_field_def_list(p: &mut Parser) { } } -fn tuple_field_def_list(p: &mut Parser) { +fn tuple_field_list(p: &mut Parser) { assert!(p.at(T!['('])); let m = p.start(); if !p.expect(T!['(']) { @@ -159,7 +159,7 @@ fn tuple_field_def_list(p: &mut Parser) { // enum S { // Uri(#[serde(with = "url_serde")] Uri), // } - attributes::outer_attributes(p); + attributes::outer_attrs(p); opt_visibility(p); if !p.at_ts(types::TYPE_FIRST) { p.error("expected a type"); diff --git a/crates/parser/src/grammar/items/consts.rs b/crates/parser/src/grammar/items/consts.rs index 35ad766dc..eb7d1f828 100644 --- a/crates/parser/src/grammar/items/consts.rs +++ b/crates/parser/src/grammar/items/consts.rs @@ -2,11 +2,11 @@ use super::*; -pub(super) fn static_def(p: &mut Parser, m: Marker) { +pub(super) fn static_(p: &mut Parser, m: Marker) { const_or_static(p, m, T![static], STATIC) } -pub(super) fn const_def(p: &mut Parser, m: Marker) { +pub(super) fn konst(p: &mut Parser, m: Marker) { const_or_static(p, m, T![const], CONST) } diff --git a/crates/parser/src/grammar/items/traits.rs b/crates/parser/src/grammar/items/traits.rs index 751ce65f2..8394020da 100644 --- a/crates/parser/src/grammar/items/traits.rs +++ b/crates/parser/src/grammar/items/traits.rs @@ -5,11 +5,11 @@ use super::*; // test trait_item // trait T: Hash + Clone where U: Copy {} // trait X: Hash + Clone where U: Copy {} -pub(super) fn trait_def(p: &mut Parser) { +pub(super) fn trait_(p: &mut Parser) { assert!(p.at(T![trait])); p.bump(T![trait]); name_r(p, ITEM_RECOVERY_SET); - type_params::opt_type_param_list(p); + type_params::opt_generic_param_list(p); // test trait_alias // trait Z = T; // trait Z = T where U: Copy; @@ -25,41 +25,19 @@ pub(super) fn trait_def(p: &mut Parser) { } type_params::opt_where_clause(p); if p.at(T!['{']) { - trait_item_list(p); + assoc_item_list(p); } else { p.error("expected `{`"); } } -// test trait_item_list -// impl F { -// type A: Clone; -// const B: i32; -// fn foo() {} -// fn bar(&self); -// } -pub(crate) fn trait_item_list(p: &mut Parser) { - assert!(p.at(T!['{'])); - let m = p.start(); - p.bump(T!['{']); - while !p.at(EOF) && !p.at(T!['}']) { - if p.at(T!['{']) { - error_block(p, "expected an item"); - continue; - } - item_or_macro(p, true); - } - p.expect(T!['}']); - m.complete(p, ASSOC_ITEM_LIST); -} - // test impl_def // impl Foo {} -pub(super) fn impl_def(p: &mut Parser) { +pub(super) fn impl_(p: &mut Parser) { assert!(p.at(T![impl])); p.bump(T![impl]); if choose_type_params_over_qpath(p) { - type_params::opt_type_param_list(p); + type_params::opt_generic_param_list(p); } // FIXME: never type @@ -74,7 +52,7 @@ pub(super) fn impl_def(p: &mut Parser) { } type_params::opt_where_clause(p); if p.at(T!['{']) { - impl_item_list(p); + assoc_item_list(p); } else { p.error("expected `{`"); } @@ -87,7 +65,7 @@ pub(super) fn impl_def(p: &mut Parser) { // fn foo() {} // fn bar(&self) {} // } -pub(crate) fn impl_item_list(p: &mut Parser) { +pub(crate) fn assoc_item_list(p: &mut Parser) { assert!(p.at(T!['{'])); let m = p.start(); p.bump(T!['{']); @@ -97,7 +75,7 @@ pub(crate) fn impl_item_list(p: &mut Parser) { // //! This is a doc comment // #![doc("This is also a doc comment")] // } - attributes::inner_attributes(p); + attributes::inner_attrs(p); while !p.at(EOF) && !p.at(T!['}']) { if p.at(T!['{']) { diff --git a/crates/parser/src/grammar/items/use_item.rs b/crates/parser/src/grammar/items/use_item.rs index 8e836a77e..20e6a13cf 100644 --- a/crates/parser/src/grammar/items/use_item.rs +++ b/crates/parser/src/grammar/items/use_item.rs @@ -2,7 +2,7 @@ use super::*; -pub(super) fn use_item(p: &mut Parser, m: Marker) { +pub(super) fn use_(p: &mut Parser, m: Marker) { assert!(p.at(T![use])); p.bump(T![use]); use_tree(p, true); @@ -80,7 +80,7 @@ fn use_tree(p: &mut Parser, top_level: bool) { // running::out::of::synonyms::for_::different::* // }; // use Trait as _; - opt_alias(p); + opt_rename(p); } T![:] if p.at(T![::]) => { p.bump(T![::]); -- cgit v1.2.3