1 //! FIXME: write short doc here
6 // trait T<U>: Hash + Clone where U: Copy {}
7 // trait X<U: Debug + Display>: Hash + Clone where U: Copy {}
8 pub(super) fn trait_(p: &mut Parser) {
9 assert!(p.at(T![trait]));
11 name_r(p, ITEM_RECOVERY_SET);
12 type_params::opt_generic_param_list(p);
15 // trait Z<U> = T<U> where U: Copy;
16 // trait Z<U> = where Self: T<U>;
18 type_params::bounds_without_colon(p);
19 type_params::opt_where_clause(p);
24 type_params::bounds(p);
26 type_params::opt_where_clause(p);
30 p.error("expected `{`");
36 pub(super) fn impl_(p: &mut Parser) {
37 assert!(p.at(T![impl]));
39 if choose_type_params_over_qpath(p) {
40 type_params::opt_generic_param_list(p);
47 // impl !Send for X {}
53 type_params::opt_where_clause(p);
57 p.error("expected `{`");
61 // test impl_item_list
68 pub(crate) fn assoc_item_list(p: &mut Parser) {
69 assert!(p.at(T!['{']));
72 // test impl_inner_attributes
75 // //! This is a doc comment
76 // #![doc("This is also a doc comment")]
78 attributes::inner_attrs(p);
80 while !p.at(EOF) && !p.at(T!['}']) {
82 error_block(p, "expected an item");
85 item_or_macro(p, true);
88 m.complete(p, ASSOC_ITEM_LIST);
91 // test impl_type_params
92 // impl<const N: u32> Bar<N> {}
93 fn choose_type_params_over_qpath(p: &Parser) -> bool {
94 // There's an ambiguity between generic parameters and qualified paths in impls.
95 // If we see `<` it may start both, so we have to inspect some following tokens.
96 // The following combinations can only start generics,
97 // but not qualified paths (with one exception):
98 // `<` `>` - empty generic parameters
99 // `<` `#` - generic parameters with attributes
100 // `<` `const` - const generic parameters
101 // `<` (LIFETIME_IDENT|IDENT) `>` - single generic parameter
102 // `<` (LIFETIME_IDENT|IDENT) `,` - first generic parameter in a list
103 // `<` (LIFETIME_IDENT|IDENT) `:` - generic parameter with bounds
104 // `<` (LIFETIME_IDENT|IDENT) `=` - generic parameter with a default
105 // The only truly ambiguous case is
106 // `<` IDENT `>` `::` IDENT ...
107 // we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`)
108 // because this is what almost always expected in practice, qualified paths in impls
109 // (`impl <Type>::AssocTy { ... }`) aren't even allowed by type checker at the moment.
113 if p.nth(1) == T![#] || p.nth(1) == T![>] || p.nth(1) == T![const] {
116 (p.nth(1) == LIFETIME_IDENT || p.nth(1) == IDENT)
117 && (p.nth(2) == T![>] || p.nth(2) == T![,] || p.nth(2) == T![:] || p.nth(2) == T![=])
120 // test_err impl_type
122 // impl Trait1 for T {}
123 // impl impl NotType {}
124 // impl Trait2 for impl NotType {}
125 pub(crate) fn impl_type(p: &mut Parser) {
127 p.error("expected trait or type");