Rollup merge of #144195 - Kivooeo:bad-attr, r=fmease,compiler-errors
Parser: Recover from attributes applied to types and generic args r? compiler Add clearer error messages for invalid attribute usage in types or generic types fixes rust-lang/rust#135017 fixes rust-lang/rust#144132
This commit is contained in:
@@ -1489,6 +1489,34 @@ pub(crate) struct AttributeOnParamType {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_attribute_on_type)]
|
||||
pub(crate) struct AttributeOnType {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
|
||||
pub fix_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_attribute_on_generic_arg)]
|
||||
pub(crate) struct AttributeOnGenericArg {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
|
||||
pub fix_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_attribute_on_empty_type)]
|
||||
pub(crate) struct AttributeOnEmptyType {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_pattern_method_param_without_body, code = E0642)]
|
||||
pub(crate) struct PatternMethodParamWithoutBody {
|
||||
|
||||
@@ -17,11 +17,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)]
|
||||
@@ -880,6 +880,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 +940,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 +962,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))
|
||||
}
|
||||
|
||||
|
||||
@@ -14,10 +14,10 @@ use thin_vec::{ThinVec, thin_vec};
|
||||
|
||||
use super::{Parser, PathStyle, SeqSep, TokenType, Trailing};
|
||||
use crate::errors::{
|
||||
self, DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType,
|
||||
FnPtrWithGenerics, FnPtrWithGenericsSugg, HelpUseLatestEdition, InvalidDynKeyword,
|
||||
LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, NestedCVariadicType,
|
||||
ReturnTypesUseThinArrow,
|
||||
self, AttributeOnEmptyType, AttributeOnType, DynAfterMut, ExpectedFnPathFoundFnKeyword,
|
||||
ExpectedMutOrConstInRawPointerType, FnPtrWithGenerics, FnPtrWithGenericsSugg,
|
||||
HelpUseLatestEdition, InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime,
|
||||
NestedCVariadicType, ReturnTypesUseThinArrow,
|
||||
};
|
||||
use crate::parser::item::FrontMatterParsingMode;
|
||||
use crate::{exp, maybe_recover_from_interpolated_ty_qpath};
|
||||
@@ -253,7 +253,27 @@ impl<'a> Parser<'a> {
|
||||
) -> PResult<'a, P<Ty>> {
|
||||
let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes;
|
||||
maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
|
||||
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);
|
||||
let attr_span = raw_attrs[0].span.to(raw_attrs.last().unwrap().span);
|
||||
let (full_span, guar) = match self.parse_ty() {
|
||||
Ok(ty) => {
|
||||
let full_span = attr_span.until(ty.span);
|
||||
let guar = self
|
||||
.dcx()
|
||||
.emit_err(AttributeOnType { span: attr_span, fix_span: full_span });
|
||||
(attr_span, guar)
|
||||
}
|
||||
Err(err) => {
|
||||
err.cancel();
|
||||
let guar = self.dcx().emit_err(AttributeOnEmptyType { span: attr_span });
|
||||
(attr_span, guar)
|
||||
}
|
||||
};
|
||||
|
||||
return Ok(self.mk_ty(full_span, TyKind::Err(guar)));
|
||||
}
|
||||
if let Some(ty) = self.eat_metavar_seq_with_matcher(
|
||||
|mv_kind| matches!(mv_kind, MetaVarKind::Ty { .. }),
|
||||
|this| this.parse_ty_no_question_mark_recover(),
|
||||
|
||||
Reference in New Issue
Block a user