Auto merge of #90076 - jackh726:wherethewhere, r=nikomatsakis

Change location of where clause on GATs

Closes #89122

~Blocked on lang FCP~

r? `@nikomatsakis`
This commit is contained in:
bors 2022-03-06 07:22:09 +00:00
commit ad0d1d71d3
52 changed files with 552 additions and 283 deletions

View file

@ -13,11 +13,12 @@ use rustc_ast::{EnumDef, FieldDef, Generics, TraitRef, Ty, TyKind, Variant, Vari
use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
use rustc_ast::{MacArgs, MacCall, MacDelimiter};
use rustc_ast_pretty::pprust;
use rustc_errors::{struct_span_err, Applicability, ErrorGuaranteed, PResult, StashKey};
use rustc_errors::{struct_span_err, Applicability, PResult, StashKey};
use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
use rustc_span::lev_distance::lev_distance;
use rustc_span::source_map::{self, Span};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::DUMMY_SP;
use std::convert::TryFrom;
use std::mem;
@ -801,44 +802,6 @@ impl<'a> Parser<'a> {
))
}
/// Emits an error that the where clause at the end of a type alias is not
/// allowed and suggests moving it.
fn error_ty_alias_where(
&self,
before_where_clause_present: bool,
before_where_clause_span: Span,
after_predicates: &[WherePredicate],
after_where_clause_span: Span,
) -> ErrorGuaranteed {
let mut err =
self.struct_span_err(after_where_clause_span, "where clause not allowed here");
if !after_predicates.is_empty() {
let mut state = crate::pprust::State::new();
if !before_where_clause_present {
state.space();
state.word_space("where");
} else {
state.word_space(",");
}
let mut first = true;
for p in after_predicates.iter() {
if !first {
state.word_space(",");
}
first = false;
state.print_where_predicate(p);
}
let suggestion = state.s.eof();
err.span_suggestion(
before_where_clause_span.shrink_to_hi(),
"move it here",
suggestion,
Applicability::MachineApplicable,
);
}
err.emit()
}
/// Parses a `type` alias with the following grammar:
/// ```
/// TypeAlias = "type" Ident Generics {":" GenericBounds}? {"=" Ty}? ";" ;
@ -851,27 +814,40 @@ impl<'a> Parser<'a> {
// Parse optional colon and param bounds.
let bounds =
if self.eat(&token::Colon) { self.parse_generic_bounds(None)? } else { Vec::new() };
generics.where_clause = self.parse_where_clause()?;
let before_where_clause = self.parse_where_clause()?;
let ty = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
if self.token.is_keyword(kw::Where) {
let after_where_clause = self.parse_where_clause()?;
let after_where_clause = self.parse_where_clause()?;
self.error_ty_alias_where(
generics.where_clause.has_where_token,
generics.where_clause.span,
&after_where_clause.predicates,
after_where_clause.span,
);
generics.where_clause.predicates.extend(after_where_clause.predicates.into_iter());
}
let where_clauses = (
TyAliasWhereClause(before_where_clause.has_where_token, before_where_clause.span),
TyAliasWhereClause(after_where_clause.has_where_token, after_where_clause.span),
);
let where_predicates_split = before_where_clause.predicates.len();
let mut predicates = before_where_clause.predicates;
predicates.extend(after_where_clause.predicates.into_iter());
let where_clause = WhereClause {
has_where_token: before_where_clause.has_where_token
|| after_where_clause.has_where_token,
predicates,
span: DUMMY_SP,
};
generics.where_clause = where_clause;
self.expect_semi()?;
Ok((ident, ItemKind::TyAlias(Box::new(TyAlias { defaultness, generics, bounds, ty }))))
Ok((
ident,
ItemKind::TyAlias(Box::new(TyAlias {
defaultness,
generics,
where_clauses,
where_predicates_split,
bounds,
ty,
})),
))
}
/// Parses a `UseTree`.