use super::*;
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_generic_param_list(p);
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!['{']) {
assoc_item_list(p);
} else {
p.error("expected `{`");
}
}
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_generic_param_list(p);
}
p.eat(T![!]);
impl_type(p);
if p.eat(T![for]) {
impl_type(p);
}
type_params::opt_where_clause(p);
if p.at(T!['{']) {
assoc_item_list(p);
} else {
p.error("expected `{`");
}
}
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);
}
p.expect(T!['}']);
m.complete(p, ASSOC_ITEM_LIST);
}
fn choose_type_params_over_qpath(p: &Parser) -> bool {
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![=])
}
pub(crate) fn impl_type(p: &mut Parser) {
if p.at(T![impl]) {
p.error("expected trait or type");
return;
}
types::type_(p);
}