]>
git.proxmox.com Git - rustc.git/blob - src/tools/rust-analyzer/crates/parser/src/grammar/items/traits.rs
4 // trait T { fn new() -> Self; }
5 pub(super) fn trait_(p
: &mut Parser
<'_
>, m
: Marker
) {
7 name_r(p
, ITEM_RECOVERY_SET
);
9 // test trait_item_generic_params
10 // trait X<U: Debug + Display> {}
11 generic_params
::opt_generic_param_list(p
);
16 generic_params
::bounds_without_colon(p
);
18 // test trait_alias_where_clause
19 // trait Z<U> = T<U> where U: Copy;
20 // trait Z<U> = where Self: T<U>;
21 generic_params
::opt_where_clause(p
);
23 m
.complete(p
, TRAIT_ALIAS
);
28 // test trait_item_bounds
29 // trait T: Hash + Clone {}
30 generic_params
::bounds(p
);
33 // test trait_item_where_clause
34 // trait T where Self: Copy {}
35 generic_params
::opt_where_clause(p
);
40 p
.error("expected `{`");
47 pub(super) fn impl_(p
: &mut Parser
<'_
>, m
: Marker
) {
49 if p
.at(T
![<]) && not_a_qualified_path(p
) {
50 generic_params
::opt_generic_param_list(p
);
53 // test impl_item_const
54 // impl const Send for S {}
61 // impl !Send for S {}
67 generic_params
::opt_where_clause(p
);
71 p
.error("expected `{`");
76 // test assoc_item_list
83 pub(crate) fn assoc_item_list(p
: &mut Parser
<'_
>) {
84 assert
!(p
.at(T
!['
{'
]));
88 // test assoc_item_list_inner_attrs
89 // impl S { #![attr] }
90 attributes
::inner_attrs(p
);
92 while !p
.at(EOF
) && !p
.at(T
!['
}'
]) {
94 error_block(p
, "expected an item");
97 item_or_macro(p
, true);
100 m
.complete(p
, ASSOC_ITEM_LIST
);
103 // test impl_type_params
104 // impl<const N: u32> Bar<N> {}
105 fn not_a_qualified_path(p
: &Parser
<'_
>) -> bool
{
106 // There's an ambiguity between generic parameters and qualified paths in impls.
107 // If we see `<` it may start both, so we have to inspect some following tokens.
108 // The following combinations can only start generics,
109 // but not qualified paths (with one exception):
110 // `<` `>` - empty generic parameters
111 // `<` `#` - generic parameters with attributes
112 // `<` `const` - const generic parameters
113 // `<` (LIFETIME_IDENT|IDENT) `>` - single generic parameter
114 // `<` (LIFETIME_IDENT|IDENT) `,` - first generic parameter in a list
115 // `<` (LIFETIME_IDENT|IDENT) `:` - generic parameter with bounds
116 // `<` (LIFETIME_IDENT|IDENT) `=` - generic parameter with a default
117 // The only truly ambiguous case is
118 // `<` IDENT `>` `::` IDENT ...
119 // we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`)
120 // because this is what almost always expected in practice, qualified paths in impls
121 // (`impl <Type>::AssocTy { ... }`) aren't even allowed by type checker at the moment.
122 if p
.nth(1) == T
![#] || p.nth(1) == T![>] || p.nth(1) == T![const] {
125 (p
.nth(1) == LIFETIME_IDENT
|| p
.nth(1) == IDENT
)
126 && (p
.nth(2) == T
![>] || p
.nth(2) == T
![,] || p
.nth(2) == T
![:] || p
.nth(2) == T
![=])
129 // test_err impl_type
131 // impl Trait1 for T {}
132 // impl impl NotType {}
133 // impl Trait2 for impl NotType {}
134 pub(crate) fn impl_type(p
: &mut Parser
<'_
>) {
136 p
.error("expected trait or type");