diff options
| author | Michael Goulet <michael@errs.io> | 2023-03-16 22:00:08 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-03-28 01:14:28 +0000 |
| commit | 8b592db27afdc9edac084520bca98508da53c996 (patch) | |
| tree | 3a2638e8dd3656cfdb5aeed9b68e349efb2c2183 /compiler/rustc_parse/src | |
| parent | 104aacb49fb37265fb923e3b779de3c388abd92c (diff) | |
| download | rust-8b592db27afdc9edac084520bca98508da53c996.tar.gz rust-8b592db27afdc9edac084520bca98508da53c996.zip | |
Add `(..)` syntax for RTN
Diffstat (limited to 'compiler/rustc_parse/src')
| -rw-r--r-- | compiler/rustc_parse/src/errors.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/diagnostics.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/path.rs | 29 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/ty.rs | 7 |
4 files changed, 39 insertions, 8 deletions
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index a9d116012ae..aead216b61c 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2316,3 +2316,11 @@ pub struct BoxSyntaxRemoved<'a> { pub span: Span, pub code: &'a str, } + +#[derive(Diagnostic)] +#[diag(parse_bad_return_type_notation_output)] +pub(crate) struct BadReturnTypeNotationOutput { + #[primary_span] + #[suggestion(code = "", applicability = "maybe-incorrect")] + pub span: Span, +} diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 9544afd3d6d..5210b8fe69d 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -989,8 +989,7 @@ impl<'a> Parser<'a> { } if self.token.kind == token::OpenDelim(Delimiter::Parenthesis) { // Recover from bad turbofish: `foo.collect::Vec<_>()`. - let args = AngleBracketedArgs { args, span }.into(); - segment.args = args; + segment.args = Some(AngleBracketedArgs { args, span }.into()); self.sess.emit_err(GenericParamsWithoutAngleBrackets { span, diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 72f230e628d..f1c9f0109f8 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -1,6 +1,6 @@ use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{Parser, Restrictions, TokenType}; -use crate::maybe_whole; +use crate::{errors, maybe_whole}; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, Token, TokenKind}; use rustc_ast::{ @@ -290,6 +290,25 @@ impl<'a> Parser<'a> { })?; let span = lo.to(self.prev_token.span); AngleBracketedArgs { args, span }.into() + } else if self.token.kind == token::OpenDelim(Delimiter::Parenthesis) + // FIXME(return_type_notation): Could also recover `...` here. + && self.look_ahead(1, |tok| tok.kind == token::DotDot) + { + let lo = self.token.span; + self.bump(); + self.bump(); + self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; + let span = lo.to(self.prev_token.span); + self.sess.gated_spans.gate(sym::return_type_notation, span); + + if self.eat_noexpect(&token::RArrow) { + let lo = self.prev_token.span; + let ty = self.parse_ty()?; + self.sess + .emit_err(errors::BadReturnTypeNotationOutput { span: lo.to(ty.span) }); + } + + P(GenericArgs::ReturnTypeNotation(span)) } else { // `(T, U) -> R` let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?; @@ -300,7 +319,7 @@ impl<'a> Parser<'a> { ParenthesizedArgs { span, inputs, inputs_span, output }.into() }; - PathSegment { ident, args, id: ast::DUMMY_NODE_ID } + PathSegment { ident, args: Some(args), id: ast::DUMMY_NODE_ID } } else { // Generic arguments are not found. PathSegment::from_ident(ident) @@ -550,8 +569,10 @@ impl<'a> Parser<'a> { // Gate associated type bounds, e.g., `Iterator<Item: Ord>`. if let AssocConstraintKind::Bound { .. } = kind { - if gen_args.as_ref().map_or(false, |args| args.is_parenthesized()) { - self.sess.gated_spans.gate(sym::return_type_notation, span); + if gen_args.as_ref().map_or(false, |args| { + matches!(args, GenericArgs::ReturnTypeNotation(..)) + }) { + // This is already gated in `parse_path_segment` } else { self.sess.gated_spans.gate(sym::associated_type_bounds, span); } diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 3d9d2cc62e3..400c8dbe9bc 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -1059,8 +1059,11 @@ impl<'a> Parser<'a> { output, } .into(); - *fn_path_segment = - ast::PathSegment { ident: fn_path_segment.ident, args, id: ast::DUMMY_NODE_ID }; + *fn_path_segment = ast::PathSegment { + ident: fn_path_segment.ident, + args: Some(args), + id: ast::DUMMY_NODE_ID, + }; // Convert parsed `<'a>` in `Fn<'a>` into `for<'a>`. let mut generic_params = lifetimes |
