Skip to content

Commit c20b4f5

Browse files
committed
Change syntax for TyAlias where clauses
1 parent 379e94f commit c20b4f5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+392
-253
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2662,10 +2662,23 @@ pub struct Trait {
26622662
pub items: Vec<P<AssocItem>>,
26632663
}
26642664

2665+
/// The location of a where clause on a `TyAlias` (`Span`) and whether there was
2666+
/// a `where` keyword (`bool`). This is split out from `WhereClause`, since there
2667+
/// are two locations for where clause on type aliases, but their predicates
2668+
/// are concatenated together.
2669+
#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
2670+
pub struct TyAliasWhereClause(pub bool, pub Span);
2671+
26652672
#[derive(Clone, Encodable, Decodable, Debug)]
26662673
pub struct TyAlias {
26672674
pub defaultness: Defaultness,
26682675
pub generics: Generics,
2676+
/// The span information for the two where clauses (before equals, after equals)
2677+
pub where_clauses: (TyAliasWhereClause, TyAliasWhereClause),
2678+
/// The index in `generics.where_clause.predicates` that would split into
2679+
/// predicates from the where clause before the equals and the predicates
2680+
/// from the where clause after the equals
2681+
pub where_predicates_split: usize,
26692682
pub bounds: GenericBounds,
26702683
pub ty: Option<P<Ty>>,
26712684
}

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,9 +1018,13 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
10181018
}
10191019
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
10201020
ItemKind::GlobalAsm(asm) => noop_visit_inline_asm(asm, vis),
1021-
ItemKind::TyAlias(box TyAlias { defaultness, generics, bounds, ty }) => {
1021+
ItemKind::TyAlias(box TyAlias {
1022+
defaultness, generics, where_clauses, bounds, ty, ..
1023+
}) => {
10221024
visit_defaultness(defaultness, vis);
10231025
vis.visit_generics(generics);
1026+
vis.visit_span(&mut where_clauses.0.1);
1027+
vis.visit_span(&mut where_clauses.1.1);
10241028
visit_bounds(bounds, vis);
10251029
visit_opt(ty, |ty| vis.visit_ty(ty));
10261030
}
@@ -1087,9 +1091,18 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>(
10871091
visit_fn_sig(sig, visitor);
10881092
visit_opt(body, |body| visitor.visit_block(body));
10891093
}
1090-
AssocItemKind::TyAlias(box TyAlias { defaultness, generics, bounds, ty }) => {
1094+
AssocItemKind::TyAlias(box TyAlias {
1095+
defaultness,
1096+
generics,
1097+
where_clauses,
1098+
bounds,
1099+
ty,
1100+
..
1101+
}) => {
10911102
visit_defaultness(defaultness, visitor);
10921103
visitor.visit_generics(generics);
1104+
visitor.visit_span(&mut where_clauses.0.1);
1105+
visitor.visit_span(&mut where_clauses.1.1);
10931106
visit_bounds(bounds, visitor);
10941107
visit_opt(ty, |ty| visitor.visit_ty(ty));
10951108
}
@@ -1152,9 +1165,18 @@ pub fn noop_flat_map_foreign_item<T: MutVisitor>(
11521165
visit_fn_sig(sig, visitor);
11531166
visit_opt(body, |body| visitor.visit_block(body));
11541167
}
1155-
ForeignItemKind::TyAlias(box TyAlias { defaultness, generics, bounds, ty }) => {
1168+
ForeignItemKind::TyAlias(box TyAlias {
1169+
defaultness,
1170+
generics,
1171+
where_clauses,
1172+
bounds,
1173+
ty,
1174+
..
1175+
}) => {
11561176
visit_defaultness(defaultness, visitor);
11571177
visitor.visit_generics(generics);
1178+
visitor.visit_span(&mut where_clauses.0.1);
1179+
visitor.visit_span(&mut where_clauses.1.1);
11581180
visit_bounds(bounds, visitor);
11591181
visit_opt(ty, |ty| visitor.visit_ty(ty));
11601182
}

compiler/rustc_ast/src/visit.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
303303
walk_list!(visitor, visit_foreign_item, &foreign_module.items);
304304
}
305305
ItemKind::GlobalAsm(ref asm) => walk_inline_asm(visitor, asm),
306-
ItemKind::TyAlias(box TyAlias { defaultness: _, ref generics, ref bounds, ref ty }) => {
306+
ItemKind::TyAlias(box TyAlias { ref generics, ref bounds, ref ty, .. }) => {
307307
visitor.visit_generics(generics);
308308
walk_list!(visitor, visit_param_bound, bounds);
309309
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
559559
let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, body.as_deref());
560560
visitor.visit_fn(kind, span, id);
561561
}
562-
ForeignItemKind::TyAlias(box TyAlias { defaultness: _, generics, bounds, ty }) => {
562+
ForeignItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
563563
visitor.visit_generics(generics);
564564
walk_list!(visitor, visit_param_bound, bounds);
565565
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,
665665
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, body.as_deref());
666666
visitor.visit_fn(kind, span, id);
667667
}
668-
AssocItemKind::TyAlias(box TyAlias { defaultness: _, generics, bounds, ty }) => {
668+
AssocItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
669669
visitor.visit_generics(generics);
670670
walk_list!(visitor, visit_param_bound, bounds);
671671
walk_list!(visitor, visit_ty, ty);

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
277277
ItemKind::GlobalAsm(ref asm) => {
278278
hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm))
279279
}
280-
ItemKind::TyAlias(box TyAlias { ref generics, ty: Some(ref ty), .. }) => {
280+
ItemKind::TyAlias(box TyAlias {
281+
ref generics,
282+
where_clauses,
283+
ty: Some(ref ty),
284+
..
285+
}) => {
281286
// We lower
282287
//
283288
// type Foo = impl Trait
@@ -292,16 +297,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
292297
capturable_lifetimes: &mut FxHashSet::default(),
293298
},
294299
);
300+
let mut generics = generics.clone();
301+
generics.where_clause.has_where_token = where_clauses.0.0;
302+
generics.where_clause.span = where_clauses.0.1;
295303
let generics = self.lower_generics(
296-
generics,
304+
&generics,
297305
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
298306
);
299307
hir::ItemKind::TyAlias(ty, generics)
300308
}
301-
ItemKind::TyAlias(box TyAlias { ref generics, ty: None, .. }) => {
309+
ItemKind::TyAlias(box TyAlias {
310+
ref generics, ref where_clauses, ty: None, ..
311+
}) => {
302312
let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err));
313+
let mut generics = generics.clone();
314+
generics.where_clause.has_where_token = where_clauses.0.0;
315+
generics.where_clause.span = where_clauses.0.1;
303316
let generics = self.lower_generics(
304-
generics,
317+
&generics,
305318
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
306319
);
307320
hir::ItemKind::TyAlias(ty, generics)
@@ -832,18 +845,27 @@ impl<'hir> LoweringContext<'_, 'hir> {
832845
);
833846
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)))
834847
}
835-
AssocItemKind::TyAlias(box TyAlias { ref generics, ref bounds, ref ty, .. }) => {
848+
AssocItemKind::TyAlias(box TyAlias {
849+
ref generics,
850+
where_clauses,
851+
ref bounds,
852+
ref ty,
853+
..
854+
}) => {
836855
let ty = ty.as_ref().map(|x| {
837856
self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
838857
});
858+
let mut generics = generics.clone();
859+
generics.where_clause.has_where_token = where_clauses.1.0;
860+
generics.where_clause.span = where_clauses.1.1;
839861
let generics = self.lower_generics(
840-
generics,
862+
&generics,
841863
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
842864
);
843865
let kind = hir::TraitItemKind::Type(
844866
self.lower_param_bounds(
845867
bounds,
846-
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
868+
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
847869
),
848870
ty,
849871
);
@@ -917,9 +939,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
917939

918940
(generics, hir::ImplItemKind::Fn(sig, body_id))
919941
}
920-
AssocItemKind::TyAlias(box TyAlias { generics, ty, .. }) => {
942+
AssocItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => {
943+
let mut generics = generics.clone();
944+
generics.where_clause.has_where_token = where_clauses.1.0;
945+
generics.where_clause.span = where_clauses.1.1;
921946
let generics = self.lower_generics(
922-
generics,
947+
&generics,
923948
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
924949
);
925950
let kind = match ty {

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_ast::ptr::P;
1111
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
1212
use rustc_ast::walk_list;
1313
use rustc_ast::*;
14-
use rustc_ast_pretty::pprust;
14+
use rustc_ast_pretty::pprust::{self, State};
1515
use rustc_data_structures::fx::FxHashMap;
1616
use rustc_errors::{error_code, pluralize, struct_span_err, Applicability};
1717
use rustc_parse::validate_attr;
@@ -122,6 +122,40 @@ impl<'a> AstValidator<'a> {
122122
}
123123
}
124124

125+
fn check_gat_where(
126+
&self,
127+
before_predicates: &[WherePredicate],
128+
where_clauses: (ast::TyAliasWhereClause, ast::TyAliasWhereClause),
129+
) {
130+
let sess = &self.session;
131+
if !before_predicates.is_empty() {
132+
let mut state = State::new();
133+
if !where_clauses.1.0 {
134+
state.space();
135+
state.word_space("where");
136+
} else {
137+
state.word_space(",");
138+
}
139+
let mut first = true;
140+
for p in before_predicates.iter() {
141+
if !first {
142+
state.word_space(",");
143+
}
144+
first = false;
145+
state.print_where_predicate(p);
146+
}
147+
let suggestion = state.s.eof();
148+
sess.struct_span_err(where_clauses.0.1, "where clause not allowed here")
149+
.span_suggestion(
150+
where_clauses.1.1.shrink_to_hi(),
151+
"move it here",
152+
suggestion,
153+
Applicability::MachineApplicable,
154+
)
155+
.emit();
156+
}
157+
}
158+
125159
fn with_banned_assoc_ty_bound(&mut self, f: impl FnOnce(&mut Self)) {
126160
let old = mem::replace(&mut self.is_assoc_ty_bound_banned, true);
127161
f(self);
@@ -454,7 +488,7 @@ impl<'a> AstValidator<'a> {
454488
.emit();
455489
}
456490

457-
fn check_foreign_ty_genericless(&self, generics: &Generics) {
491+
fn check_foreign_ty_genericless(&self, generics: &Generics, where_span: Span) {
458492
let cannot_have = |span, descr, remove_descr| {
459493
self.err_handler()
460494
.struct_span_err(
@@ -477,7 +511,7 @@ impl<'a> AstValidator<'a> {
477511
}
478512

479513
if !generics.where_clause.predicates.is_empty() {
480-
cannot_have(generics.where_clause.span, "`where` clauses", "`where` clause");
514+
cannot_have(where_span, "`where` clauses", "`where` clause");
481515
}
482516
}
483517

@@ -1223,13 +1257,25 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
12231257
let msg = "free static item without body";
12241258
self.error_item_without_body(item.span, "static", msg, " = <expr>;");
12251259
}
1226-
ItemKind::TyAlias(box TyAlias { defaultness, ref bounds, ref ty, .. }) => {
1260+
ItemKind::TyAlias(box TyAlias {
1261+
defaultness,
1262+
where_clauses,
1263+
ref bounds,
1264+
ref ty,
1265+
..
1266+
}) => {
12271267
self.check_defaultness(item.span, defaultness);
12281268
if ty.is_none() {
12291269
let msg = "free type alias without body";
12301270
self.error_item_without_body(item.span, "type", msg, " = <type>;");
12311271
}
12321272
self.check_type_no_bounds(bounds, "this context");
1273+
if where_clauses.1.0 {
1274+
self.err_handler().span_err(
1275+
where_clauses.1.1,
1276+
"where clauses are not allowed after the type for type aliases",
1277+
)
1278+
}
12331279
}
12341280
_ => {}
12351281
}
@@ -1245,11 +1291,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
12451291
self.check_foreign_fn_headerless(fi.ident, fi.span, sig.header);
12461292
self.check_foreign_item_ascii_only(fi.ident);
12471293
}
1248-
ForeignItemKind::TyAlias(box TyAlias { defaultness, generics, bounds, ty, .. }) => {
1294+
ForeignItemKind::TyAlias(box TyAlias {
1295+
defaultness,
1296+
generics,
1297+
where_clauses,
1298+
bounds,
1299+
ty,
1300+
..
1301+
}) => {
12491302
self.check_defaultness(fi.span, *defaultness);
12501303
self.check_foreign_kind_bodyless(fi.ident, "type", ty.as_ref().map(|b| b.span));
12511304
self.check_type_no_bounds(bounds, "`extern` blocks");
1252-
self.check_foreign_ty_genericless(generics);
1305+
self.check_foreign_ty_genericless(generics, where_clauses.0.1);
12531306
self.check_foreign_item_ascii_only(fi.ident);
12541307
}
12551308
ForeignItemKind::Static(_, _, body) => {
@@ -1503,9 +1556,22 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
15031556
AssocItemKind::Fn(box Fn { body, .. }) => {
15041557
self.check_impl_item_provided(item.span, body, "function", " { <body> }");
15051558
}
1506-
AssocItemKind::TyAlias(box TyAlias { bounds, ty, .. }) => {
1559+
AssocItemKind::TyAlias(box TyAlias {
1560+
generics,
1561+
where_clauses,
1562+
where_predicates_split,
1563+
bounds,
1564+
ty,
1565+
..
1566+
}) => {
15071567
self.check_impl_item_provided(item.span, ty, "type", " = <type>;");
15081568
self.check_type_no_bounds(bounds, "`impl`s");
1569+
if ty.is_some() {
1570+
self.check_gat_where(
1571+
generics.where_clause.predicates.split_at(*where_predicates_split).0,
1572+
*where_clauses,
1573+
);
1574+
}
15091575
}
15101576
_ => {}
15111577
}

0 commit comments

Comments
 (0)