Refactor where
predicates, and reserve for attributes support
This commit is contained in:
parent
67a8c64259
commit
161221da9e
44 changed files with 394 additions and 408 deletions
|
@ -1,6 +1,7 @@
|
|||
use ast::token::Delimiter;
|
||||
use rustc_ast::{
|
||||
self as ast, AttrVec, GenericBounds, GenericParam, GenericParamKind, TyKind, WhereClause, token,
|
||||
self as ast, AttrVec, DUMMY_NODE_ID, GenericBounds, GenericParam, GenericParamKind, TyKind,
|
||||
WhereClause, token,
|
||||
};
|
||||
use rustc_errors::{Applicability, PResult};
|
||||
use rustc_span::Span;
|
||||
|
@ -14,8 +15,8 @@ use crate::errors::{
|
|||
WhereClauseBeforeTupleStructBodySugg,
|
||||
};
|
||||
|
||||
enum PredicateOrStructBody {
|
||||
Predicate(ast::WherePredicate),
|
||||
enum PredicateKindOrStructBody {
|
||||
PredicateKind(ast::WherePredicateKind),
|
||||
StructBody(ThinVec<ast::FieldDef>),
|
||||
}
|
||||
|
||||
|
@ -218,10 +219,11 @@ impl<'a> Parser<'a> {
|
|||
} else if this.token.can_begin_type() {
|
||||
// Trying to write an associated type bound? (#26271)
|
||||
let snapshot = this.create_snapshot_for_diagnostic();
|
||||
match this.parse_ty_where_predicate() {
|
||||
Ok(where_predicate) => {
|
||||
let lo = this.token.span;
|
||||
match this.parse_ty_where_predicate_kind() {
|
||||
Ok(_) => {
|
||||
this.dcx().emit_err(errors::BadAssocTypeBounds {
|
||||
span: where_predicate.span(),
|
||||
span: lo.to(this.prev_token.span),
|
||||
});
|
||||
// FIXME - try to continue parsing other generics?
|
||||
}
|
||||
|
@ -340,31 +342,33 @@ impl<'a> Parser<'a> {
|
|||
loop {
|
||||
let where_sp = where_lo.to(self.prev_token.span);
|
||||
let pred_lo = self.token.span;
|
||||
if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
|
||||
let kind = if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
|
||||
let lifetime = self.expect_lifetime();
|
||||
// Bounds starting with a colon are mandatory, but possibly empty.
|
||||
self.expect(&token::Colon)?;
|
||||
let bounds = self.parse_lt_param_bounds();
|
||||
where_clause.predicates.push(ast::WherePredicate::RegionPredicate(
|
||||
ast::WhereRegionPredicate {
|
||||
span: pred_lo.to(self.prev_token.span),
|
||||
lifetime,
|
||||
bounds,
|
||||
},
|
||||
));
|
||||
ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate {
|
||||
lifetime,
|
||||
bounds,
|
||||
})
|
||||
} else if self.check_type() {
|
||||
match self.parse_ty_where_predicate_or_recover_tuple_struct_body(
|
||||
match self.parse_ty_where_predicate_kind_or_recover_tuple_struct_body(
|
||||
struct_, pred_lo, where_sp,
|
||||
)? {
|
||||
PredicateOrStructBody::Predicate(pred) => where_clause.predicates.push(pred),
|
||||
PredicateOrStructBody::StructBody(body) => {
|
||||
PredicateKindOrStructBody::PredicateKind(kind) => kind,
|
||||
PredicateKindOrStructBody::StructBody(body) => {
|
||||
tuple_struct_body = Some(body);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
};
|
||||
where_clause.predicates.push(ast::WherePredicate {
|
||||
kind,
|
||||
id: DUMMY_NODE_ID,
|
||||
span: pred_lo.to(self.prev_token.span),
|
||||
});
|
||||
|
||||
let prev_token = self.prev_token.span;
|
||||
let ate_comma = self.eat(&token::Comma);
|
||||
|
@ -384,12 +388,12 @@ impl<'a> Parser<'a> {
|
|||
Ok((where_clause, tuple_struct_body))
|
||||
}
|
||||
|
||||
fn parse_ty_where_predicate_or_recover_tuple_struct_body(
|
||||
fn parse_ty_where_predicate_kind_or_recover_tuple_struct_body(
|
||||
&mut self,
|
||||
struct_: Option<(Ident, Span)>,
|
||||
pred_lo: Span,
|
||||
where_sp: Span,
|
||||
) -> PResult<'a, PredicateOrStructBody> {
|
||||
) -> PResult<'a, PredicateKindOrStructBody> {
|
||||
let mut snapshot = None;
|
||||
|
||||
if let Some(struct_) = struct_
|
||||
|
@ -399,8 +403,8 @@ impl<'a> Parser<'a> {
|
|||
snapshot = Some((struct_, self.create_snapshot_for_diagnostic()));
|
||||
};
|
||||
|
||||
match self.parse_ty_where_predicate() {
|
||||
Ok(pred) => Ok(PredicateOrStructBody::Predicate(pred)),
|
||||
match self.parse_ty_where_predicate_kind() {
|
||||
Ok(pred) => Ok(PredicateKindOrStructBody::PredicateKind(pred)),
|
||||
Err(type_err) => {
|
||||
let Some(((struct_name, body_insertion_point), mut snapshot)) = snapshot else {
|
||||
return Err(type_err);
|
||||
|
@ -436,7 +440,7 @@ impl<'a> Parser<'a> {
|
|||
});
|
||||
|
||||
self.restore_snapshot(snapshot);
|
||||
Ok(PredicateOrStructBody::StructBody(body))
|
||||
Ok(PredicateKindOrStructBody::StructBody(body))
|
||||
}
|
||||
Ok(_) => Err(type_err),
|
||||
Err(body_err) => {
|
||||
|
@ -448,8 +452,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_ty_where_predicate(&mut self) -> PResult<'a, ast::WherePredicate> {
|
||||
let lo = self.token.span;
|
||||
fn parse_ty_where_predicate_kind(&mut self) -> PResult<'a, ast::WherePredicateKind> {
|
||||
// Parse optional `for<'a, 'b>`.
|
||||
// This `for` is parsed greedily and applies to the whole predicate,
|
||||
// the bounded type can have its own `for` applying only to it.
|
||||
|
@ -464,8 +467,7 @@ impl<'a> Parser<'a> {
|
|||
let ty = self.parse_ty_for_where_clause()?;
|
||||
if self.eat(&token::Colon) {
|
||||
let bounds = self.parse_generic_bounds()?;
|
||||
Ok(ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
|
||||
span: lo.to(self.prev_token.span),
|
||||
Ok(ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate {
|
||||
bound_generic_params: lifetime_defs,
|
||||
bounded_ty: ty,
|
||||
bounds,
|
||||
|
@ -474,11 +476,7 @@ impl<'a> Parser<'a> {
|
|||
// FIXME: We are just dropping the binders in lifetime_defs on the floor here.
|
||||
} else if self.eat(&token::Eq) || self.eat(&token::EqEq) {
|
||||
let rhs_ty = self.parse_ty()?;
|
||||
Ok(ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
|
||||
span: lo.to(self.prev_token.span),
|
||||
lhs_ty: ty,
|
||||
rhs_ty,
|
||||
}))
|
||||
Ok(ast::WherePredicateKind::EqPredicate(ast::WhereEqPredicate { lhs_ty: ty, rhs_ty }))
|
||||
} else {
|
||||
self.maybe_recover_bounds_doubled_colon(&ty)?;
|
||||
self.unexpected_any()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue