use super::*;
pub(super) fn trait_(p: &mut Parser<'_>, m: Marker) {
p.bump(T![trait]);
name_r(p, ITEM_RECOVERY_SET);
generic_params::opt_generic_param_list(p);
if p.eat(T![=]) {
generic_params::bounds_without_colon(p);
generic_params::opt_where_clause(p);
p.expect(T![;]);
m.complete(p, TRAIT);
return;
}
if p.at(T![:]) {
generic_params::bounds(p);
}
generic_params::opt_where_clause(p);
if p.at(T!['{']) {
assoc_item_list(p);
} else {
p.error("expected `{`");
}
m.complete(p, TRAIT);
}
pub(super) fn impl_(p: &mut Parser<'_>, m: Marker) {
p.bump(T![impl]);
if p.at(T![<]) && not_a_qualified_path(p) {
generic_params::opt_generic_param_list(p);
}
p.eat(T![const]);
if p.at(T![!]) && !p.nth_at(1, T!['{']) {
p.eat(T![!]);
}
impl_type(p);
if p.eat(T![for]) {
impl_type(p);
}
generic_params::opt_where_clause(p);
if p.at(T!['{']) {
assoc_item_list(p);
} else {
p.error("expected `{`");
}
m.complete(p, IMPL);
}
pub(crate) fn assoc_item_list(p: &mut Parser<'_>) {
assert!(p.at(T!['{']));
let m = p.start();
p.bump(T!['{']);
attributes::inner_attrs(p);
while !p.at(EOF) && !p.at(T!['}']) {
if p.at(T!['{']) {
error_block(p, "expected an item");
continue;
}
item_or_macro(p, true, false);
}
p.expect(T!['}']);
m.complete(p, ASSOC_ITEM_LIST);
}
fn not_a_qualified_path(p: &Parser<'_>) -> bool {
if [T![#], T![>], T![const]].contains(&p.nth(1)) {
return true;
}
([LIFETIME_IDENT, IDENT].contains(&p.nth(1)))
&& ([T![>], T![,], T![:], T![=]].contains(&p.nth(2)))
}
pub(crate) fn impl_type(p: &mut Parser<'_>) {
if p.at(T![impl]) {
p.error("expected trait or type");
return;
}
types::type_(p);
}