Retire ast::TyAliasWhereClauses.

This commit is contained in:
Camille Gillot
2025-10-15 04:04:36 +00:00
parent 1d23d06800
commit 15c91bf308
12 changed files with 170 additions and 158 deletions

View File

@@ -3636,49 +3636,26 @@ pub struct Trait {
pub items: ThinVec<Box<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.
///
/// Take this example:
/// ```ignore (only-for-syntax-highlight)
/// trait Foo {
/// type Assoc<'a, 'b> where Self: 'a, Self: 'b;
/// }
/// impl Foo for () {
/// type Assoc<'a, 'b> where Self: 'a = () where Self: 'b;
/// // ^^^^^^^^^^^^^^ first where clause
/// // ^^^^^^^^^^^^^^ second where clause
/// }
/// ```
///
/// If there is no where clause, then this is `false` with `DUMMY_SP`.
#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
pub struct TyAliasWhereClause {
pub has_where_token: bool,
pub span: Span,
}
/// The span information for the two where clauses on a `TyAlias`.
#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
pub struct TyAliasWhereClauses {
/// Before the equals sign.
pub before: TyAliasWhereClause,
/// After the equals sign.
pub after: TyAliasWhereClause,
/// The index in `TyAlias.generics.where_clause.predicates` that would split
/// into predicates from the where clause before the equals sign and the ones
/// from the where clause after the equals sign.
pub split: usize,
}
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct TyAlias {
pub defaultness: Defaultness,
pub ident: Ident,
pub generics: Generics,
pub where_clauses: TyAliasWhereClauses,
/// There are two locations for where clause on type aliases. This represents the second
/// where clause, before the semicolon. The first where clause is stored inside `generics`.
///
/// Take this example:
/// ```ignore (only-for-syntax-highlight)
/// trait Foo {
/// type Assoc<'a, 'b> where Self: 'a, Self: 'b;
/// }
/// impl Foo for () {
/// type Assoc<'a, 'b> where Self: 'a = () where Self: 'b;
/// // ^^^^^^^^^^^^^^ before where clause
/// // ^^^^^^^^^^^^^^ after where clause
/// }
/// ```
pub after_where_clause: WhereClause,
#[visitable(extra = BoundKind::Bound)]
pub bounds: GenericBounds,
pub ty: Option<Box<Ty>>,

View File

@@ -471,8 +471,6 @@ macro_rules! common_visitor_and_walkers {
TraitBoundModifiers,
TraitObjectSyntax,
TyAlias,
TyAliasWhereClause,
TyAliasWhereClauses,
TyKind,
TyPatKind,
UnOp,

View File

@@ -36,20 +36,18 @@ pub(super) struct ItemLowerer<'a, 'hir> {
/// clause if it exists.
fn add_ty_alias_where_clause(
generics: &mut ast::Generics,
mut where_clauses: TyAliasWhereClauses,
after_where_clause: &ast::WhereClause,
prefer_first: bool,
) {
generics.where_clause.predicates.extend_from_slice(&after_where_clause.predicates);
let mut before = (generics.where_clause.has_where_token, generics.where_clause.span);
let mut after = (after_where_clause.has_where_token, after_where_clause.span);
if !prefer_first {
(where_clauses.before, where_clauses.after) = (where_clauses.after, where_clauses.before);
(before, after) = (after, before);
}
let where_clause =
if where_clauses.before.has_where_token || !where_clauses.after.has_where_token {
where_clauses.before
} else {
where_clauses.after
};
generics.where_clause.has_where_token = where_clause.has_where_token;
generics.where_clause.span = where_clause.span;
(generics.where_clause.has_where_token, generics.where_clause.span) =
if before.0 || !after.0 { before } else { after };
}
impl<'a, 'hir> ItemLowerer<'a, 'hir> {
@@ -271,7 +269,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm))));
hir::ItemKind::GlobalAsm { asm, fake_body }
}
ItemKind::TyAlias(box TyAlias { ident, generics, where_clauses, ty, .. }) => {
ItemKind::TyAlias(box TyAlias { ident, generics, after_where_clause, ty, .. }) => {
// We lower
//
// type Foo = impl Trait
@@ -282,7 +280,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// opaque type Foo1: Trait
let ident = self.lower_ident(*ident);
let mut generics = generics.clone();
add_ty_alias_where_clause(&mut generics, *where_clauses, true);
add_ty_alias_where_clause(&mut generics, after_where_clause, true);
let (generics, ty) = self.lower_generics(
&generics,
id,
@@ -901,10 +899,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
)
}
AssocItemKind::Type(box TyAlias {
ident, generics, where_clauses, bounds, ty, ..
ident,
generics,
after_where_clause,
bounds,
ty,
..
}) => {
let mut generics = generics.clone();
add_ty_alias_where_clause(&mut generics, *where_clauses, false);
add_ty_alias_where_clause(&mut generics, after_where_clause, false);
let (generics, kind) = self.lower_generics(
&generics,
i.id,
@@ -1070,9 +1073,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
(*ident, (generics, hir::ImplItemKind::Fn(sig, body_id)))
}
AssocItemKind::Type(box TyAlias { ident, generics, where_clauses, ty, .. }) => {
AssocItemKind::Type(box TyAlias {
ident, generics, after_where_clause, ty, ..
}) => {
let mut generics = generics.clone();
add_ty_alias_where_clause(&mut generics, *where_clauses, false);
add_ty_alias_where_clause(&mut generics, after_where_clause, false);
(
*ident,
self.lower_generics(

View File

@@ -145,25 +145,24 @@ impl<'a> AstValidator<'a> {
&mut self,
ty_alias: &TyAlias,
) -> Result<(), errors::WhereClauseBeforeTypeAlias> {
if ty_alias.ty.is_none() || !ty_alias.where_clauses.before.has_where_token {
if ty_alias.ty.is_none() || !ty_alias.generics.where_clause.has_where_token {
return Ok(());
}
let (before_predicates, after_predicates) =
ty_alias.generics.where_clause.predicates.split_at(ty_alias.where_clauses.split);
let span = ty_alias.where_clauses.before.span;
let span = ty_alias.generics.where_clause.span;
let sugg = if !before_predicates.is_empty() || !ty_alias.where_clauses.after.has_where_token
let sugg = if !ty_alias.generics.where_clause.predicates.is_empty()
|| !ty_alias.after_where_clause.has_where_token
{
let mut state = State::new();
if !ty_alias.where_clauses.after.has_where_token {
if !ty_alias.after_where_clause.has_where_token {
state.space();
state.word_space("where");
}
let mut first = after_predicates.is_empty();
for p in before_predicates {
let mut first = ty_alias.after_where_clause.predicates.is_empty();
for p in &ty_alias.generics.where_clause.predicates {
if !first {
state.word_space(",");
}
@@ -174,7 +173,7 @@ impl<'a> AstValidator<'a> {
errors::WhereClauseBeforeTypeAliasSugg::Move {
left: span,
snippet: state.s.eof(),
right: ty_alias.where_clauses.after.span.shrink_to_hi(),
right: ty_alias.after_where_clause.span.shrink_to_hi(),
}
} else {
errors::WhereClauseBeforeTypeAliasSugg::Remove { span }
@@ -566,11 +565,7 @@ impl<'a> AstValidator<'a> {
self.dcx().emit_err(errors::BoundInContext { span, ctx });
}
fn check_foreign_ty_genericless(
&self,
generics: &Generics,
where_clauses: &TyAliasWhereClauses,
) {
fn check_foreign_ty_genericless(&self, generics: &Generics, after_where_clause: &WhereClause) {
let cannot_have = |span, descr, remove_descr| {
self.dcx().emit_err(errors::ExternTypesCannotHave {
span,
@@ -584,14 +579,14 @@ impl<'a> AstValidator<'a> {
cannot_have(generics.span, "generic parameters", "generic parameters");
}
let check_where_clause = |where_clause: TyAliasWhereClause| {
let check_where_clause = |where_clause: &WhereClause| {
if where_clause.has_where_token {
cannot_have(where_clause.span, "`where` clauses", "`where` clause");
}
};
check_where_clause(where_clauses.before);
check_where_clause(where_clauses.after);
check_where_clause(&generics.where_clause);
check_where_clause(&after_where_clause);
}
fn check_foreign_kind_bodyless(&self, ident: Ident, kind: &str, body_span: Option<Span>) {
@@ -1261,7 +1256,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
visit::walk_item(self, item);
}
ItemKind::TyAlias(
ty_alias @ box TyAlias { defaultness, bounds, where_clauses, ty, .. },
ty_alias @ box TyAlias { defaultness, bounds, after_where_clause, ty, .. },
) => {
self.check_defaultness(item.span, *defaultness);
if ty.is_none() {
@@ -1276,9 +1271,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if let Err(err) = self.check_type_alias_where_clause_location(ty_alias) {
self.dcx().emit_err(err);
}
} else if where_clauses.after.has_where_token {
} else if after_where_clause.has_where_token {
self.dcx().emit_err(errors::WhereClauseAfterTypeAlias {
span: where_clauses.after.span,
span: after_where_clause.span,
help: self.sess.is_nightly_build(),
});
}
@@ -1308,7 +1303,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
defaultness,
ident,
generics,
where_clauses,
after_where_clause,
bounds,
ty,
..
@@ -1316,7 +1311,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.check_defaultness(fi.span, *defaultness);
self.check_foreign_kind_bodyless(*ident, "type", ty.as_ref().map(|b| b.span));
self.check_type_no_bounds(bounds, "`extern` blocks");
self.check_foreign_ty_genericless(generics, where_clauses);
self.check_foreign_ty_genericless(generics, after_where_clause);
self.check_foreign_item_ascii_only(*ident);
}
ForeignItemKind::Static(box StaticItem { ident, safety, expr, .. }) => {

View File

@@ -59,14 +59,14 @@ impl<'a> State<'a> {
defaultness,
ident,
generics,
where_clauses,
after_where_clause,
bounds,
ty,
}) => {
self.print_associated_type(
*ident,
generics,
*where_clauses,
after_where_clause,
bounds,
ty.as_deref(),
vis,
@@ -127,14 +127,12 @@ impl<'a> State<'a> {
&mut self,
ident: Ident,
generics: &ast::Generics,
where_clauses: ast::TyAliasWhereClauses,
after_where_clause: &ast::WhereClause,
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_clauses.split);
let (cb, ib) = self.head("");
self.print_visibility(vis);
self.print_defaultness(defaultness);
@@ -145,13 +143,13 @@ impl<'a> State<'a> {
self.word_nbsp(":");
self.print_type_bounds(bounds);
}
self.print_where_clause_parts(where_clauses.before.has_where_token, before_predicates);
self.print_where_clause(&generics.where_clause);
if let Some(ty) = ty {
self.space();
self.word_space("=");
self.print_type(ty);
}
self.print_where_clause_parts(where_clauses.after.has_where_token, after_predicates);
self.print_where_clause(&after_where_clause);
self.word(";");
self.end(ib);
self.end(cb);
@@ -283,14 +281,14 @@ impl<'a> State<'a> {
defaultness,
ident,
generics,
where_clauses,
after_where_clause,
bounds,
ty,
}) => {
self.print_associated_type(
*ident,
generics,
*where_clauses,
after_where_clause,
bounds,
ty.as_deref(),
&item.vis,
@@ -585,14 +583,14 @@ impl<'a> State<'a> {
defaultness,
ident,
generics,
where_clauses,
after_where_clause,
bounds,
ty,
}) => {
self.print_associated_type(
*ident,
generics,
*where_clauses,
after_where_clause,
bounds,
ty.as_deref(),
vis,
@@ -759,14 +757,7 @@ impl<'a> State<'a> {
}
fn print_where_clause(&mut self, where_clause: &ast::WhereClause) {
self.print_where_clause_parts(where_clause.has_where_token, &where_clause.predicates);
}
fn print_where_clause_parts(
&mut self,
has_where_token: bool,
predicates: &[ast::WherePredicate],
) {
let ast::WhereClause { has_where_token, ref predicates, span: _ } = *where_clause;
if predicates.is_empty() && !has_where_token {
return;
}

View File

@@ -610,7 +610,7 @@ impl<'a> TraitDef<'a> {
defaultness: ast::Defaultness::Final,
ident,
generics: Generics::default(),
where_clauses: ast::TyAliasWhereClauses::default(),
after_where_clause: ast::WhereClause::default(),
bounds: Vec::new(),
ty: Some(type_def.to_ty(cx, self.span, type_ident, generics)),
})),

View File

@@ -1041,40 +1041,19 @@ impl<'a> Parser<'a> {
// Parse optional colon and param bounds.
let bounds = if self.eat(exp!(Colon)) { self.parse_generic_bounds()? } else { Vec::new() };
let before_where_clause = self.parse_where_clause()?;
generics.where_clause = self.parse_where_clause()?;
let ty = if self.eat(exp!(Eq)) { Some(self.parse_ty()?) } else { None };
let after_where_clause = self.parse_where_clause()?;
let where_clauses = TyAliasWhereClauses {
before: TyAliasWhereClause {
has_where_token: before_where_clause.has_where_token,
span: before_where_clause.span,
},
after: TyAliasWhereClause {
has_where_token: after_where_clause.has_where_token,
span: after_where_clause.span,
},
split: before_where_clause.predicates.len(),
};
let mut predicates = before_where_clause.predicates;
predicates.extend(after_where_clause.predicates);
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(ItemKind::TyAlias(Box::new(TyAlias {
defaultness,
ident,
generics,
where_clauses,
after_where_clause,
bounds,
ty,
})))