diff options
| author | bors <bors@rust-lang.org> | 2021-12-29 12:07:33 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-12-29 12:07:33 +0000 |
| commit | 2b67c30bfece00357d5fc09d99b49f21066f04ba (patch) | |
| tree | ad36e3e5492f2cd163e10b47db2b0bc3359ef337 /compiler/rustc_parse/src/parser | |
| parent | 6211dd7250e9b8e80733f74911ca88c661adb1a9 (diff) | |
| parent | 949769cf3bb3f81293fbdaaac64d38bd97942158 (diff) | |
| download | rust-2b67c30bfece00357d5fc09d99b49f21066f04ba.tar.gz rust-2b67c30bfece00357d5fc09d99b49f21066f04ba.zip | |
Auto merge of #92397 - matthiaskrgr:rollup-xnfou17, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #92075 (rustdoc: Only special case struct fields for intra-doc links, not enum variants) - #92118 (Parse and suggest moving where clauses after equals for type aliases) - #92237 (Visit expressions in-order when resolving pattern bindings) - #92340 (rustdoc: Start cleaning up search index generation) - #92351 (Add long error explanation for E0227) - #92371 (Remove pretty printer space inside block with only outer attrs) - #92372 (Print space after formal generic params in fn type) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_parse/src/parser')
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 618aa3fd002..d335ef8788b 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -794,6 +794,44 @@ 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, + ) { + 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}? ";" ; @@ -806,9 +844,24 @@ 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 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()?; + + 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()); + } + self.expect_semi()?; Ok((ident, ItemKind::TyAlias(Box::new(TyAlias { defaultness, generics, bounds, ty })))) |
