diff options
Diffstat (limited to 'compiler/rustc_parse/src/parser/path.rs')
| -rw-r--r-- | compiler/rustc_parse/src/parser/path.rs | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 1f4049f197f..a6ec3ea4245 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -1,7 +1,6 @@ use std::mem; use ast::token::IdentIsRaw; -use rustc_ast::ptr::P; use rustc_ast::token::{self, MetaVarKind, Token, TokenKind}; use rustc_ast::{ self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocItemConstraint, @@ -17,11 +16,11 @@ use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{Parser, Restrictions, TokenType}; use crate::ast::{PatKind, TyKind}; use crate::errors::{ - self, FnPathFoundNamedParams, PathFoundAttributeInParams, PathFoundCVariadicParams, - PathSingleColon, PathTripleColon, + self, AttributeOnEmptyType, AttributeOnGenericArg, FnPathFoundNamedParams, + PathFoundAttributeInParams, PathFoundCVariadicParams, PathSingleColon, PathTripleColon, }; use crate::exp; -use crate::parser::{CommaRecoveryMode, RecoverColon, RecoverComma}; +use crate::parser::{CommaRecoveryMode, ExprKind, RecoverColon, RecoverComma}; /// Specifies how to parse a path. #[derive(Copy, Clone, PartialEq)] @@ -75,7 +74,7 @@ impl<'a> Parser<'a> { /// `<T as U>::a` /// `<T as U>::F::a<S>` (without disambiguator) /// `<T as U>::F::a::<S>` (with disambiguator) - pub(super) fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (P<QSelf>, Path)> { + pub(super) fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (Box<QSelf>, Path)> { let lo = self.prev_token.span; let ty = self.parse_ty()?; @@ -105,7 +104,7 @@ impl<'a> Parser<'a> { self.expect(exp!(PathSep))?; } - let qself = P(QSelf { ty, path_span, position: path.segments.len() }); + let qself = Box::new(QSelf { ty, path_span, position: path.segments.len() }); if !is_import_coupler { self.parse_path_segments(&mut path.segments, style, None)?; } @@ -380,7 +379,7 @@ impl<'a> Parser<'a> { .emit_err(errors::BadReturnTypeNotationOutput { span, suggestion }); } - P(ast::GenericArgs::ParenthesizedElided(span)) + Box::new(ast::GenericArgs::ParenthesizedElided(span)) } else { // `(T, U) -> R` @@ -842,7 +841,7 @@ impl<'a> Parser<'a> { /// - A literal. /// - A numeric literal prefixed by `-`. /// - A single-segment path. - pub(super) fn expr_is_valid_const_arg(&self, expr: &P<rustc_ast::Expr>) -> bool { + pub(super) fn expr_is_valid_const_arg(&self, expr: &Box<rustc_ast::Expr>) -> bool { match &expr.kind { ast::ExprKind::Block(_, _) | ast::ExprKind::Lit(_) @@ -880,6 +879,12 @@ impl<'a> Parser<'a> { &mut self, ty_generics: Option<&Generics>, ) -> PResult<'a, Option<GenericArg>> { + let mut attr_span: Option<Span> = None; + if self.token == token::Pound && self.look_ahead(1, |t| *t == token::OpenBracket) { + let attrs_wrapper = self.parse_outer_attributes()?; + let raw_attrs = attrs_wrapper.take_for_recovery(self.psess); + attr_span = Some(raw_attrs[0].span.to(raw_attrs.last().unwrap().span)); + } let start = self.token.span; let arg = if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) { // Parse lifetime argument. @@ -934,6 +939,9 @@ impl<'a> Parser<'a> { } } else if self.token.is_keyword(kw::Const) { return self.recover_const_param_declaration(ty_generics); + } else if let Some(attr_span) = attr_span { + let diag = self.dcx().create_err(AttributeOnEmptyType { span: attr_span }); + return Err(diag); } else { // Fall back by trying to parse a const-expr expression. If we successfully do so, // then we should report an error that it needs to be wrapped in braces. @@ -953,6 +961,22 @@ impl<'a> Parser<'a> { } } }; + + if let Some(attr_span) = attr_span { + let guar = self.dcx().emit_err(AttributeOnGenericArg { + span: attr_span, + fix_span: attr_span.until(arg.span()), + }); + return Ok(Some(match arg { + GenericArg::Type(_) => GenericArg::Type(self.mk_ty(attr_span, TyKind::Err(guar))), + GenericArg::Const(_) => { + let error_expr = self.mk_expr(attr_span, ExprKind::Err(guar)); + GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value: error_expr }) + } + GenericArg::Lifetime(lt) => GenericArg::Lifetime(lt), + })); + } + Ok(Some(arg)) } |
