@@ -11,11 +11,13 @@ use rustc_ast::ptr::P;
1111use rustc_ast:: visit:: { self , AssocCtxt , FnCtxt , FnKind , Visitor } ;
1212use rustc_ast:: walk_list;
1313use rustc_ast:: * ;
14- use rustc_ast_pretty:: pprust;
14+ use rustc_ast_pretty:: pprust:: { self , State } ;
1515use rustc_data_structures:: fx:: FxHashMap ;
1616use rustc_errors:: { error_code, pluralize, struct_span_err, Applicability } ;
1717use rustc_parse:: validate_attr;
18- use rustc_session:: lint:: builtin:: { MISSING_ABI , PATTERNS_IN_FNS_WITHOUT_BODY } ;
18+ use rustc_session:: lint:: builtin:: {
19+ DEPRECATED_WHERE_CLAUSE_LOCATION , MISSING_ABI , PATTERNS_IN_FNS_WITHOUT_BODY ,
20+ } ;
1921use rustc_session:: lint:: { BuiltinLintDiagnostics , LintBuffer } ;
2022use rustc_session:: Session ;
2123use rustc_span:: source_map:: Spanned ;
@@ -122,6 +124,42 @@ impl<'a> AstValidator<'a> {
122124 }
123125 }
124126
127+ fn check_gat_where (
128+ & mut self ,
129+ id : NodeId ,
130+ before_predicates : & [ WherePredicate ] ,
131+ where_clauses : ( ast:: TyAliasWhereClause , ast:: TyAliasWhereClause ) ,
132+ ) {
133+ if !before_predicates. is_empty ( ) {
134+ let mut state = State :: new ( ) ;
135+ if !where_clauses. 1 . 0 {
136+ state. space ( ) ;
137+ state. word_space ( "where" ) ;
138+ } else {
139+ state. word_space ( "," ) ;
140+ }
141+ let mut first = true ;
142+ for p in before_predicates. iter ( ) {
143+ if !first {
144+ state. word_space ( "," ) ;
145+ }
146+ first = false ;
147+ state. print_where_predicate ( p) ;
148+ }
149+ let suggestion = state. s . eof ( ) ;
150+ self . lint_buffer . buffer_lint_with_diagnostic (
151+ DEPRECATED_WHERE_CLAUSE_LOCATION ,
152+ id,
153+ where_clauses. 0 . 1 ,
154+ "where clause not allowed here" ,
155+ BuiltinLintDiagnostics :: DeprecatedWhereclauseLocation (
156+ where_clauses. 1 . 1 . shrink_to_hi ( ) ,
157+ suggestion,
158+ ) ,
159+ ) ;
160+ }
161+ }
162+
125163 fn with_banned_assoc_ty_bound ( & mut self , f : impl FnOnce ( & mut Self ) ) {
126164 let old = mem:: replace ( & mut self . is_assoc_ty_bound_banned , true ) ;
127165 f ( self ) ;
@@ -454,7 +492,7 @@ impl<'a> AstValidator<'a> {
454492 . emit ( ) ;
455493 }
456494
457- fn check_foreign_ty_genericless ( & self , generics : & Generics ) {
495+ fn check_foreign_ty_genericless ( & self , generics : & Generics , where_span : Span ) {
458496 let cannot_have = |span, descr, remove_descr| {
459497 self . err_handler ( )
460498 . struct_span_err (
@@ -477,7 +515,7 @@ impl<'a> AstValidator<'a> {
477515 }
478516
479517 if !generics. where_clause . predicates . is_empty ( ) {
480- cannot_have ( generics . where_clause . span , "`where` clauses" , "`where` clause" ) ;
518+ cannot_have ( where_span , "`where` clauses" , "`where` clause" ) ;
481519 }
482520 }
483521
@@ -1223,13 +1261,29 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
12231261 let msg = "free static item without body" ;
12241262 self . error_item_without_body ( item. span , "static" , msg, " = <expr>;" ) ;
12251263 }
1226- ItemKind :: TyAlias ( box TyAlias { defaultness, ref bounds, ref ty, .. } ) => {
1264+ ItemKind :: TyAlias ( box TyAlias {
1265+ defaultness,
1266+ where_clauses,
1267+ ref bounds,
1268+ ref ty,
1269+ ..
1270+ } ) => {
12271271 self . check_defaultness ( item. span , defaultness) ;
12281272 if ty. is_none ( ) {
12291273 let msg = "free type alias without body" ;
12301274 self . error_item_without_body ( item. span , "type" , msg, " = <type>;" ) ;
12311275 }
12321276 self . check_type_no_bounds ( bounds, "this context" ) ;
1277+ if where_clauses. 1 . 0 {
1278+ let mut err = self . err_handler ( ) . struct_span_err (
1279+ where_clauses. 1 . 1 ,
1280+ "where clauses are not allowed after the type for type aliases" ,
1281+ ) ;
1282+ err. note (
1283+ "see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information" ,
1284+ ) ;
1285+ err. emit ( ) ;
1286+ }
12331287 }
12341288 _ => { }
12351289 }
@@ -1245,11 +1299,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
12451299 self . check_foreign_fn_headerless ( fi. ident , fi. span , sig. header ) ;
12461300 self . check_foreign_item_ascii_only ( fi. ident ) ;
12471301 }
1248- ForeignItemKind :: TyAlias ( box TyAlias { defaultness, generics, bounds, ty, .. } ) => {
1302+ ForeignItemKind :: TyAlias ( box TyAlias {
1303+ defaultness,
1304+ generics,
1305+ where_clauses,
1306+ bounds,
1307+ ty,
1308+ ..
1309+ } ) => {
12491310 self . check_defaultness ( fi. span , * defaultness) ;
12501311 self . check_foreign_kind_bodyless ( fi. ident , "type" , ty. as_ref ( ) . map ( |b| b. span ) ) ;
12511312 self . check_type_no_bounds ( bounds, "`extern` blocks" ) ;
1252- self . check_foreign_ty_genericless ( generics) ;
1313+ self . check_foreign_ty_genericless ( generics, where_clauses . 0 . 1 ) ;
12531314 self . check_foreign_item_ascii_only ( fi. ident ) ;
12541315 }
12551316 ForeignItemKind :: Static ( _, _, body) => {
@@ -1503,9 +1564,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
15031564 AssocItemKind :: Fn ( box Fn { body, .. } ) => {
15041565 self . check_impl_item_provided ( item. span , body, "function" , " { <body> }" ) ;
15051566 }
1506- AssocItemKind :: TyAlias ( box TyAlias { bounds, ty, .. } ) => {
1567+ AssocItemKind :: TyAlias ( box TyAlias {
1568+ generics,
1569+ where_clauses,
1570+ where_predicates_split,
1571+ bounds,
1572+ ty,
1573+ ..
1574+ } ) => {
15071575 self . check_impl_item_provided ( item. span , ty, "type" , " = <type>;" ) ;
15081576 self . check_type_no_bounds ( bounds, "`impl`s" ) ;
1577+ if ty. is_some ( ) {
1578+ self . check_gat_where (
1579+ item. id ,
1580+ generics. where_clause . predicates . split_at ( * where_predicates_split) . 0 ,
1581+ * where_clauses,
1582+ ) ;
1583+ }
15091584 }
15101585 _ => { }
15111586 }
0 commit comments