]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #61438 - estebank:generics-span, r=varkor
authorMazdak Farrokhzad <twingoow@gmail.com>
Sun, 2 Jun 2019 13:23:49 +0000 (15:23 +0200)
committerGitHub <noreply@github.com>
Sun, 2 Jun 2019 13:23:49 +0000 (15:23 +0200)
Point at individual type args on arg count mismatch

- Point at individual type arguments on arg count mismatch
- Make generics always have a valid span, even when there are no args
- Explain that `impl Trait` introduces an implicit type argument

Fix #55991.

1  2 
src/libsyntax/parse/parser.rs

index 92c27f883d1a9ec882d3a12fd36ca009148d916a,36460e75d879e65b8b678694f8606d8833b87970..7bc95ad03693880920f7481ace84b5d9b08fb33a
@@@ -5050,21 -5050,22 +5050,22 @@@ impl<'a> Parser<'a> 
      /// where   typaramseq = ( typaram ) | ( typaram , typaramseq )
      fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
          let span_lo = self.span;
-         if self.eat_lt() {
+         let (params, span) = if self.eat_lt() {
              let params = self.parse_generic_params()?;
              self.expect_gt()?;
-             Ok(ast::Generics {
-                 params,
-                 where_clause: WhereClause {
-                     id: ast::DUMMY_NODE_ID,
-                     predicates: Vec::new(),
-                     span: DUMMY_SP,
-                 },
-                 span: span_lo.to(self.prev_span),
-             })
+             (params, span_lo.to(self.prev_span))
          } else {
-             Ok(ast::Generics::default())
-         }
+             (vec![], self.prev_span.between(self.span))
+         };
+         Ok(ast::Generics {
+             params,
+             where_clause: WhereClause {
+                 id: ast::DUMMY_NODE_ID,
+                 predicates: Vec::new(),
+                 span: DUMMY_SP,
+             },
+             span,
+         })
      }
  
      /// Parses generic args (within a path segment) with recovery for extra leading angle brackets.
              return Ok(Some(item));
          }
  
 -        // `unsafe async fn` or `async fn`
 -        if (
 -            self.check_keyword(kw::Unsafe) &&
 -            self.is_keyword_ahead(1, &[kw::Async])
 -        ) || (
 -            self.check_keyword(kw::Async) &&
 -            self.is_keyword_ahead(1, &[kw::Fn])
 -        )
 -        {
 -            // ASYNC FUNCTION ITEM
 -            let unsafety = self.parse_unsafety();
 -            self.expect_keyword(kw::Async)?;
 -            let async_span = self.prev_span;
 -            self.expect_keyword(kw::Fn)?;
 -            let fn_span = self.prev_span;
 -            let (ident, item_, extra_attrs) =
 -                self.parse_item_fn(unsafety,
 -                                   respan(async_span, IsAsync::Async {
 -                                       closure_id: ast::DUMMY_NODE_ID,
 -                                       return_impl_trait_id: ast::DUMMY_NODE_ID,
 -                                       arguments: Vec::new(),
 -                                   }),
 -                                   respan(fn_span, Constness::NotConst),
 -                                   Abi::Rust)?;
 -            let prev_span = self.prev_span;
 -            let item = self.mk_item(lo.to(prev_span),
 -                                    ident,
 -                                    item_,
 -                                    visibility,
 -                                    maybe_append(attrs, extra_attrs));
 -            if self.span.rust_2015() {
 -                self.diagnostic().struct_span_err_with_code(
 -                    async_span,
 -                    "`async fn` is not permitted in the 2015 edition",
 -                    DiagnosticId::Error("E0670".into())
 -                ).emit();
 +        // Parse `async unsafe? fn`.
 +        if self.check_keyword(kw::Async) {
 +            let async_span = self.span;
 +            if self.is_keyword_ahead(1, &[kw::Fn])
 +                || self.is_keyword_ahead(2, &[kw::Fn])
 +            {
 +                // ASYNC FUNCTION ITEM
 +                self.bump(); // `async`
 +                let unsafety = self.parse_unsafety(); // `unsafe`?
 +                self.expect_keyword(kw::Fn)?; // `fn`
 +                let fn_span = self.prev_span;
 +                let (ident, item_, extra_attrs) =
 +                    self.parse_item_fn(unsafety,
 +                                    respan(async_span, IsAsync::Async {
 +                                        closure_id: ast::DUMMY_NODE_ID,
 +                                        return_impl_trait_id: ast::DUMMY_NODE_ID,
 +                                        arguments: Vec::new(),
 +                                    }),
 +                                    respan(fn_span, Constness::NotConst),
 +                                    Abi::Rust)?;
 +                let prev_span = self.prev_span;
 +                let item = self.mk_item(lo.to(prev_span),
 +                                        ident,
 +                                        item_,
 +                                        visibility,
 +                                        maybe_append(attrs, extra_attrs));
 +                if self.span.rust_2015() {
 +                    self.diagnostic().struct_span_err_with_code(
 +                        async_span,
 +                        "`async fn` is not permitted in the 2015 edition",
 +                        DiagnosticId::Error("E0670".into())
 +                    ).emit();
 +                }
 +                return Ok(Some(item));
              }
 -            return Ok(Some(item));
          }
          if self.check_keyword(kw::Unsafe) &&
              self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])