Change syntax for TyAlias where clauses
This commit is contained in:
parent
379e94f5a4
commit
c20b4f5584
46 changed files with 394 additions and 255 deletions
|
@ -2662,10 +2662,23 @@ pub struct Trait {
|
|||
pub items: Vec<P<AssocItem>>,
|
||||
}
|
||||
|
||||
/// The location of a where clause on a `TyAlias` (`Span`) and whether there was
|
||||
/// a `where` keyword (`bool`). This is split out from `WhereClause`, since there
|
||||
/// are two locations for where clause on type aliases, but their predicates
|
||||
/// are concatenated together.
|
||||
#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
|
||||
pub struct TyAliasWhereClause(pub bool, pub Span);
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct TyAlias {
|
||||
pub defaultness: Defaultness,
|
||||
pub generics: Generics,
|
||||
/// The span information for the two where clauses (before equals, after equals)
|
||||
pub where_clauses: (TyAliasWhereClause, TyAliasWhereClause),
|
||||
/// The index in `generics.where_clause.predicates` that would split into
|
||||
/// predicates from the where clause before the equals and the predicates
|
||||
/// from the where clause after the equals
|
||||
pub where_predicates_split: usize,
|
||||
pub bounds: GenericBounds,
|
||||
pub ty: Option<P<Ty>>,
|
||||
}
|
||||
|
|
|
@ -1018,9 +1018,13 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
|
|||
}
|
||||
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
|
||||
ItemKind::GlobalAsm(asm) => noop_visit_inline_asm(asm, vis),
|
||||
ItemKind::TyAlias(box TyAlias { defaultness, generics, bounds, ty }) => {
|
||||
ItemKind::TyAlias(box TyAlias {
|
||||
defaultness, generics, where_clauses, bounds, ty, ..
|
||||
}) => {
|
||||
visit_defaultness(defaultness, vis);
|
||||
vis.visit_generics(generics);
|
||||
vis.visit_span(&mut where_clauses.0.1);
|
||||
vis.visit_span(&mut where_clauses.1.1);
|
||||
visit_bounds(bounds, vis);
|
||||
visit_opt(ty, |ty| vis.visit_ty(ty));
|
||||
}
|
||||
|
@ -1087,9 +1091,18 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>(
|
|||
visit_fn_sig(sig, visitor);
|
||||
visit_opt(body, |body| visitor.visit_block(body));
|
||||
}
|
||||
AssocItemKind::TyAlias(box TyAlias { defaultness, generics, bounds, ty }) => {
|
||||
AssocItemKind::TyAlias(box TyAlias {
|
||||
defaultness,
|
||||
generics,
|
||||
where_clauses,
|
||||
bounds,
|
||||
ty,
|
||||
..
|
||||
}) => {
|
||||
visit_defaultness(defaultness, visitor);
|
||||
visitor.visit_generics(generics);
|
||||
visitor.visit_span(&mut where_clauses.0.1);
|
||||
visitor.visit_span(&mut where_clauses.1.1);
|
||||
visit_bounds(bounds, visitor);
|
||||
visit_opt(ty, |ty| visitor.visit_ty(ty));
|
||||
}
|
||||
|
@ -1152,9 +1165,18 @@ pub fn noop_flat_map_foreign_item<T: MutVisitor>(
|
|||
visit_fn_sig(sig, visitor);
|
||||
visit_opt(body, |body| visitor.visit_block(body));
|
||||
}
|
||||
ForeignItemKind::TyAlias(box TyAlias { defaultness, generics, bounds, ty }) => {
|
||||
ForeignItemKind::TyAlias(box TyAlias {
|
||||
defaultness,
|
||||
generics,
|
||||
where_clauses,
|
||||
bounds,
|
||||
ty,
|
||||
..
|
||||
}) => {
|
||||
visit_defaultness(defaultness, visitor);
|
||||
visitor.visit_generics(generics);
|
||||
visitor.visit_span(&mut where_clauses.0.1);
|
||||
visitor.visit_span(&mut where_clauses.1.1);
|
||||
visit_bounds(bounds, visitor);
|
||||
visit_opt(ty, |ty| visitor.visit_ty(ty));
|
||||
}
|
||||
|
|
|
@ -303,7 +303,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
|
|||
walk_list!(visitor, visit_foreign_item, &foreign_module.items);
|
||||
}
|
||||
ItemKind::GlobalAsm(ref asm) => walk_inline_asm(visitor, asm),
|
||||
ItemKind::TyAlias(box TyAlias { defaultness: _, ref generics, ref bounds, ref ty }) => {
|
||||
ItemKind::TyAlias(box TyAlias { ref generics, ref bounds, ref ty, .. }) => {
|
||||
visitor.visit_generics(generics);
|
||||
walk_list!(visitor, visit_param_bound, bounds);
|
||||
walk_list!(visitor, visit_ty, ty);
|
||||
|
@ -559,7 +559,7 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignI
|
|||
let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, body.as_deref());
|
||||
visitor.visit_fn(kind, span, id);
|
||||
}
|
||||
ForeignItemKind::TyAlias(box TyAlias { defaultness: _, generics, bounds, ty }) => {
|
||||
ForeignItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
|
||||
visitor.visit_generics(generics);
|
||||
walk_list!(visitor, visit_param_bound, bounds);
|
||||
walk_list!(visitor, visit_ty, ty);
|
||||
|
@ -665,7 +665,7 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem,
|
|||
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, body.as_deref());
|
||||
visitor.visit_fn(kind, span, id);
|
||||
}
|
||||
AssocItemKind::TyAlias(box TyAlias { defaultness: _, generics, bounds, ty }) => {
|
||||
AssocItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
|
||||
visitor.visit_generics(generics);
|
||||
walk_list!(visitor, visit_param_bound, bounds);
|
||||
walk_list!(visitor, visit_ty, ty);
|
||||
|
|
|
@ -277,7 +277,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
ItemKind::GlobalAsm(ref asm) => {
|
||||
hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm))
|
||||
}
|
||||
ItemKind::TyAlias(box TyAlias { ref generics, ty: Some(ref ty), .. }) => {
|
||||
ItemKind::TyAlias(box TyAlias {
|
||||
ref generics,
|
||||
where_clauses,
|
||||
ty: Some(ref ty),
|
||||
..
|
||||
}) => {
|
||||
// We lower
|
||||
//
|
||||
// type Foo = impl Trait
|
||||
|
@ -292,16 +297,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
capturable_lifetimes: &mut FxHashSet::default(),
|
||||
},
|
||||
);
|
||||
let mut generics = generics.clone();
|
||||
generics.where_clause.has_where_token = where_clauses.0.0;
|
||||
generics.where_clause.span = where_clauses.0.1;
|
||||
let generics = self.lower_generics(
|
||||
generics,
|
||||
&generics,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|
||||
);
|
||||
hir::ItemKind::TyAlias(ty, generics)
|
||||
}
|
||||
ItemKind::TyAlias(box TyAlias { ref generics, ty: None, .. }) => {
|
||||
ItemKind::TyAlias(box TyAlias {
|
||||
ref generics, ref where_clauses, ty: None, ..
|
||||
}) => {
|
||||
let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err));
|
||||
let mut generics = generics.clone();
|
||||
generics.where_clause.has_where_token = where_clauses.0.0;
|
||||
generics.where_clause.span = where_clauses.0.1;
|
||||
let generics = self.lower_generics(
|
||||
generics,
|
||||
&generics,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|
||||
);
|
||||
hir::ItemKind::TyAlias(ty, generics)
|
||||
|
@ -832,18 +845,27 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
);
|
||||
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)))
|
||||
}
|
||||
AssocItemKind::TyAlias(box TyAlias { ref generics, ref bounds, ref ty, .. }) => {
|
||||
AssocItemKind::TyAlias(box TyAlias {
|
||||
ref generics,
|
||||
where_clauses,
|
||||
ref bounds,
|
||||
ref ty,
|
||||
..
|
||||
}) => {
|
||||
let ty = ty.as_ref().map(|x| {
|
||||
self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
|
||||
});
|
||||
let mut generics = generics.clone();
|
||||
generics.where_clause.has_where_token = where_clauses.1.0;
|
||||
generics.where_clause.span = where_clauses.1.1;
|
||||
let generics = self.lower_generics(
|
||||
generics,
|
||||
&generics,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|
||||
);
|
||||
let kind = hir::TraitItemKind::Type(
|
||||
self.lower_param_bounds(
|
||||
bounds,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|
||||
),
|
||||
ty,
|
||||
);
|
||||
|
@ -917,9 +939,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
|
||||
(generics, hir::ImplItemKind::Fn(sig, body_id))
|
||||
}
|
||||
AssocItemKind::TyAlias(box TyAlias { generics, ty, .. }) => {
|
||||
AssocItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => {
|
||||
let mut generics = generics.clone();
|
||||
generics.where_clause.has_where_token = where_clauses.1.0;
|
||||
generics.where_clause.span = where_clauses.1.1;
|
||||
let generics = self.lower_generics(
|
||||
generics,
|
||||
&generics,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|
||||
);
|
||||
let kind = match ty {
|
||||
|
|
|
@ -11,7 +11,7 @@ use rustc_ast::ptr::P;
|
|||
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
|
||||
use rustc_ast::walk_list;
|
||||
use rustc_ast::*;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_ast_pretty::pprust::{self, State};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{error_code, pluralize, struct_span_err, Applicability};
|
||||
use rustc_parse::validate_attr;
|
||||
|
@ -122,6 +122,40 @@ impl<'a> AstValidator<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_gat_where(
|
||||
&self,
|
||||
before_predicates: &[WherePredicate],
|
||||
where_clauses: (ast::TyAliasWhereClause, ast::TyAliasWhereClause),
|
||||
) {
|
||||
let sess = &self.session;
|
||||
if !before_predicates.is_empty() {
|
||||
let mut state = State::new();
|
||||
if !where_clauses.1.0 {
|
||||
state.space();
|
||||
state.word_space("where");
|
||||
} else {
|
||||
state.word_space(",");
|
||||
}
|
||||
let mut first = true;
|
||||
for p in before_predicates.iter() {
|
||||
if !first {
|
||||
state.word_space(",");
|
||||
}
|
||||
first = false;
|
||||
state.print_where_predicate(p);
|
||||
}
|
||||
let suggestion = state.s.eof();
|
||||
sess.struct_span_err(where_clauses.0.1, "where clause not allowed here")
|
||||
.span_suggestion(
|
||||
where_clauses.1.1.shrink_to_hi(),
|
||||
"move it here",
|
||||
suggestion,
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
fn with_banned_assoc_ty_bound(&mut self, f: impl FnOnce(&mut Self)) {
|
||||
let old = mem::replace(&mut self.is_assoc_ty_bound_banned, true);
|
||||
f(self);
|
||||
|
@ -454,7 +488,7 @@ impl<'a> AstValidator<'a> {
|
|||
.emit();
|
||||
}
|
||||
|
||||
fn check_foreign_ty_genericless(&self, generics: &Generics) {
|
||||
fn check_foreign_ty_genericless(&self, generics: &Generics, where_span: Span) {
|
||||
let cannot_have = |span, descr, remove_descr| {
|
||||
self.err_handler()
|
||||
.struct_span_err(
|
||||
|
@ -477,7 +511,7 @@ impl<'a> AstValidator<'a> {
|
|||
}
|
||||
|
||||
if !generics.where_clause.predicates.is_empty() {
|
||||
cannot_have(generics.where_clause.span, "`where` clauses", "`where` clause");
|
||||
cannot_have(where_span, "`where` clauses", "`where` clause");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1223,13 +1257,25 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
let msg = "free static item without body";
|
||||
self.error_item_without_body(item.span, "static", msg, " = <expr>;");
|
||||
}
|
||||
ItemKind::TyAlias(box TyAlias { defaultness, ref bounds, ref ty, .. }) => {
|
||||
ItemKind::TyAlias(box TyAlias {
|
||||
defaultness,
|
||||
where_clauses,
|
||||
ref bounds,
|
||||
ref ty,
|
||||
..
|
||||
}) => {
|
||||
self.check_defaultness(item.span, defaultness);
|
||||
if ty.is_none() {
|
||||
let msg = "free type alias without body";
|
||||
self.error_item_without_body(item.span, "type", msg, " = <type>;");
|
||||
}
|
||||
self.check_type_no_bounds(bounds, "this context");
|
||||
if where_clauses.1.0 {
|
||||
self.err_handler().span_err(
|
||||
where_clauses.1.1,
|
||||
"where clauses are not allowed after the type for type aliases",
|
||||
)
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -1245,11 +1291,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
self.check_foreign_fn_headerless(fi.ident, fi.span, sig.header);
|
||||
self.check_foreign_item_ascii_only(fi.ident);
|
||||
}
|
||||
ForeignItemKind::TyAlias(box TyAlias { defaultness, generics, bounds, ty, .. }) => {
|
||||
ForeignItemKind::TyAlias(box TyAlias {
|
||||
defaultness,
|
||||
generics,
|
||||
where_clauses,
|
||||
bounds,
|
||||
ty,
|
||||
..
|
||||
}) => {
|
||||
self.check_defaultness(fi.span, *defaultness);
|
||||
self.check_foreign_kind_bodyless(fi.ident, "type", ty.as_ref().map(|b| b.span));
|
||||
self.check_type_no_bounds(bounds, "`extern` blocks");
|
||||
self.check_foreign_ty_genericless(generics);
|
||||
self.check_foreign_ty_genericless(generics, where_clauses.0.1);
|
||||
self.check_foreign_item_ascii_only(fi.ident);
|
||||
}
|
||||
ForeignItemKind::Static(_, _, body) => {
|
||||
|
@ -1503,9 +1556,22 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
AssocItemKind::Fn(box Fn { body, .. }) => {
|
||||
self.check_impl_item_provided(item.span, body, "function", " { <body> }");
|
||||
}
|
||||
AssocItemKind::TyAlias(box TyAlias { bounds, ty, .. }) => {
|
||||
AssocItemKind::TyAlias(box TyAlias {
|
||||
generics,
|
||||
where_clauses,
|
||||
where_predicates_split,
|
||||
bounds,
|
||||
ty,
|
||||
..
|
||||
}) => {
|
||||
self.check_impl_item_provided(item.span, ty, "type", " = <type>;");
|
||||
self.check_type_no_bounds(bounds, "`impl`s");
|
||||
if ty.is_some() {
|
||||
self.check_gat_where(
|
||||
generics.where_clause.predicates.split_at(*where_predicates_split).0,
|
||||
*where_clauses,
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
@ -36,12 +36,16 @@ impl<'a> State<'a> {
|
|||
ast::ForeignItemKind::TyAlias(box ast::TyAlias {
|
||||
defaultness,
|
||||
generics,
|
||||
where_clauses,
|
||||
where_predicates_split,
|
||||
bounds,
|
||||
ty,
|
||||
}) => {
|
||||
self.print_associated_type(
|
||||
ident,
|
||||
generics,
|
||||
*where_clauses,
|
||||
*where_predicates_split,
|
||||
bounds,
|
||||
ty.as_deref(),
|
||||
vis,
|
||||
|
@ -95,11 +99,15 @@ impl<'a> State<'a> {
|
|||
&mut self,
|
||||
ident: Ident,
|
||||
generics: &ast::Generics,
|
||||
where_clauses: (ast::TyAliasWhereClause, ast::TyAliasWhereClause),
|
||||
where_predicates_split: usize,
|
||||
bounds: &ast::GenericBounds,
|
||||
ty: Option<&ast::Ty>,
|
||||
vis: &ast::Visibility,
|
||||
defaultness: ast::Defaultness,
|
||||
) {
|
||||
let (before_predicates, after_predicates) =
|
||||
generics.where_clause.predicates.split_at(where_predicates_split);
|
||||
self.head("");
|
||||
self.print_visibility(vis);
|
||||
self.print_defaultness(defaultness);
|
||||
|
@ -107,12 +115,13 @@ impl<'a> State<'a> {
|
|||
self.print_ident(ident);
|
||||
self.print_generic_params(&generics.params);
|
||||
self.print_type_bounds(":", bounds);
|
||||
self.print_where_clause(&generics.where_clause);
|
||||
self.print_where_clause_parts(where_clauses.0.0, before_predicates);
|
||||
if let Some(ty) = ty {
|
||||
self.space();
|
||||
self.word_space("=");
|
||||
self.print_type(ty);
|
||||
}
|
||||
self.print_where_clause_parts(where_clauses.1.0, after_predicates);
|
||||
self.word(";");
|
||||
self.end(); // end inner head-block
|
||||
self.end(); // end outer head-block
|
||||
|
@ -211,6 +220,8 @@ impl<'a> State<'a> {
|
|||
ast::ItemKind::TyAlias(box ast::TyAlias {
|
||||
defaultness,
|
||||
ref generics,
|
||||
where_clauses,
|
||||
where_predicates_split,
|
||||
ref bounds,
|
||||
ref ty,
|
||||
}) => {
|
||||
|
@ -218,6 +229,8 @@ impl<'a> State<'a> {
|
|||
self.print_associated_type(
|
||||
item.ident,
|
||||
generics,
|
||||
where_clauses,
|
||||
where_predicates_split,
|
||||
bounds,
|
||||
ty,
|
||||
&item.vis,
|
||||
|
@ -496,10 +509,19 @@ impl<'a> State<'a> {
|
|||
ast::AssocItemKind::Const(def, ty, body) => {
|
||||
self.print_item_const(ident, None, ty, body.as_deref(), vis, *def);
|
||||
}
|
||||
ast::AssocItemKind::TyAlias(box ast::TyAlias { defaultness, generics, bounds, ty }) => {
|
||||
ast::AssocItemKind::TyAlias(box ast::TyAlias {
|
||||
defaultness,
|
||||
generics,
|
||||
where_clauses,
|
||||
where_predicates_split,
|
||||
bounds,
|
||||
ty,
|
||||
}) => {
|
||||
self.print_associated_type(
|
||||
ident,
|
||||
generics,
|
||||
*where_clauses,
|
||||
*where_predicates_split,
|
||||
bounds,
|
||||
ty.as_deref(),
|
||||
vis,
|
||||
|
@ -566,14 +588,22 @@ impl<'a> State<'a> {
|
|||
}
|
||||
|
||||
fn print_where_clause(&mut self, where_clause: &ast::WhereClause) {
|
||||
if where_clause.predicates.is_empty() && !where_clause.has_where_token {
|
||||
self.print_where_clause_parts(where_clause.has_where_token, &where_clause.predicates);
|
||||
}
|
||||
|
||||
crate fn print_where_clause_parts(
|
||||
&mut self,
|
||||
has_where_token: bool,
|
||||
predicates: &[ast::WherePredicate],
|
||||
) {
|
||||
if predicates.is_empty() && !has_where_token {
|
||||
return;
|
||||
}
|
||||
|
||||
self.space();
|
||||
self.word_space("where");
|
||||
|
||||
for (i, predicate) in where_clause.predicates.iter().enumerate() {
|
||||
for (i, predicate) in predicates.iter().enumerate() {
|
||||
if i != 0 {
|
||||
self.word_space(",");
|
||||
}
|
||||
|
|
|
@ -560,6 +560,11 @@ impl<'a> TraitDef<'a> {
|
|||
kind: ast::AssocItemKind::TyAlias(Box::new(ast::TyAlias {
|
||||
defaultness: ast::Defaultness::Final,
|
||||
generics: Generics::default(),
|
||||
where_clauses: (
|
||||
ast::TyAliasWhereClause::default(),
|
||||
ast::TyAliasWhereClause::default(),
|
||||
),
|
||||
where_predicates_split: 0,
|
||||
bounds: Vec::new(),
|
||||
ty: Some(type_def.to_ty(cx, self.span, type_ident, generics)),
|
||||
})),
|
||||
|
|
|
@ -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;
|
||||
|
@ -791,44 +792,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}? ";" ;
|
||||
|
@ -841,27 +804,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`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue