-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Add checks for attributes in types #144195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Two lines below, there's a preexisting It's not a blocking concern tho ig and it would stop us from recovering from |
||
|
@@ -953,6 +962,22 @@ impl<'a> Parser<'a> { | |
} | ||
} | ||
}; | ||
|
||
if let Some(attr_span) = attr_span { | ||
Kivooeo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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)) | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
//! Regression test for: <https://github.com/rust-lang/rust/issues/144132> | ||
//! <https://github.com/rust-lang/rust/issues/135017> | ||
|
||
struct Baz<const N: usize>(i32); | ||
|
||
fn main() { | ||
let _: Baz<#[cfg(any())]> = todo!(); | ||
//~^ ERROR attributes cannot be applied here | ||
} | ||
|
||
fn f(_param: #[attr]) {} | ||
//~^ ERROR attributes cannot be applied to a function parameter's type | ||
//~| ERROR expected type, found `)` | ||
|
||
fn g() -> #[attr] { 0 } | ||
//~^ ERROR attributes cannot be applied here | ||
|
||
struct S { | ||
field: #[attr], | ||
//~^ ERROR attributes cannot be applied here | ||
field1: (#[attr], i32), | ||
//~^ ERROR attributes cannot be applied here | ||
} | ||
|
||
type Tuple = (#[attr], String); | ||
//~^ ERROR attributes cannot be applied here | ||
|
||
impl #[attr] {} | ||
//~^ ERROR attributes cannot be applied here |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
error: attributes cannot be applied here | ||
--> $DIR/attribute-on-empty.rs:7:16 | ||
| | ||
LL | let _: Baz<#[cfg(any())]> = todo!(); | ||
| - ^^^^^^^^^^^^^ attributes are not allowed here | ||
| | | ||
| while parsing the type for `_` | ||
|
||
error: attributes cannot be applied to a function parameter's type | ||
--> $DIR/attribute-on-empty.rs:11:14 | ||
| | ||
LL | fn f(_param: #[attr]) {} | ||
| ^^^^^^^ attributes are not allowed here | ||
|
||
error: expected type, found `)` | ||
--> $DIR/attribute-on-empty.rs:11:21 | ||
| | ||
LL | fn f(_param: #[attr]) {} | ||
| ^ expected type | ||
|
||
error: attributes cannot be applied here | ||
--> $DIR/attribute-on-empty.rs:15:11 | ||
| | ||
LL | fn g() -> #[attr] { 0 } | ||
| ^^^^^^^ attributes are not allowed here | ||
|
||
error: attributes cannot be applied here | ||
--> $DIR/attribute-on-empty.rs:19:12 | ||
| | ||
LL | field: #[attr], | ||
| ^^^^^^^ attributes are not allowed here | ||
|
||
error: attributes cannot be applied here | ||
--> $DIR/attribute-on-empty.rs:21:14 | ||
| | ||
LL | field1: (#[attr], i32), | ||
| ^^^^^^^ attributes are not allowed here | ||
|
||
error: attributes cannot be applied here | ||
--> $DIR/attribute-on-empty.rs:25:15 | ||
| | ||
LL | type Tuple = (#[attr], String); | ||
| ^^^^^^^ attributes are not allowed here | ||
|
||
error: attributes cannot be applied here | ||
--> $DIR/attribute-on-empty.rs:28:6 | ||
| | ||
LL | impl #[attr] {} | ||
| ^^^^^^^ attributes are not allowed here | ||
|
||
error: aborting due to 8 previous errors | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
//! Regression test for: <https://github.com/rust-lang/rust/issues/144132> | ||
//! <https://github.com/rust-lang/rust/issues/135017> | ||
|
||
//@ run-rustfix | ||
|
||
#![allow(dead_code, unused_variables)] | ||
|
||
struct Foo<T>(T); | ||
struct Bar<'a>(&'a i32); | ||
struct Baz<const N: usize>(i32); | ||
|
||
fn main() { | ||
let foo: Foo<i32> = Foo(2i32); | ||
//~^ ERROR attributes cannot be applied to generic arguments | ||
|
||
let _: &'static str = "123"; | ||
//~^ ERROR attributes cannot be applied to types | ||
|
||
let _: Bar<'static> = Bar(&123); | ||
//~^ ERROR attributes cannot be applied to generic arguments | ||
|
||
let _: Baz<42> = Baz(42); | ||
//~^ ERROR attributes cannot be applied to generic arguments | ||
|
||
let _: Foo<String> = Foo(String::new()); | ||
//~^ ERROR attributes cannot be applied to generic arguments | ||
|
||
let _: Bar<'static> = Bar(&456); | ||
//~^ ERROR attributes cannot be applied to generic arguments | ||
|
||
let _generic: Box<i32> = Box::new(1); | ||
//~^ ERROR attributes cannot be applied to generic arguments | ||
|
||
let _assignment: i32 = *Box::new(1); | ||
//~^ ERROR attributes cannot be applied to types | ||
|
||
let _complex: Vec<String> = vec![]; | ||
//~^ ERROR attributes cannot be applied to generic arguments | ||
|
||
let _nested: Box<Vec<u64>> = Box::new(vec![]); | ||
//~^ ERROR attributes cannot be applied to generic arguments | ||
} | ||
|
||
fn g() -> i32 { 0 } | ||
//~^ ERROR attributes cannot be applied to types | ||
|
||
struct S { | ||
field: i32, | ||
//~^ ERROR attributes cannot be applied to types | ||
field1: (i32, i32), | ||
//~^ ERROR attributes cannot be applied to types | ||
} | ||
|
||
type Tuple = (i32, String); | ||
//~^ ERROR attributes cannot be applied to types | ||
|
||
impl S {} | ||
//~^ ERROR attributes cannot be applied to types |
Kivooeo marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
//! Regression test for: <https://github.com/rust-lang/rust/issues/144132> | ||
//! <https://github.com/rust-lang/rust/issues/135017> | ||
//@ run-rustfix | ||
|
||
#![allow(dead_code, unused_variables)] | ||
|
||
struct Foo<T>(T); | ||
struct Bar<'a>(&'a i32); | ||
struct Baz<const N: usize>(i32); | ||
|
||
fn main() { | ||
let foo: Foo<#[cfg(not(wrong))] i32> = Foo(2i32); | ||
//~^ ERROR attributes cannot be applied to generic arguments | ||
|
||
let _: #[attr] &'static str = "123"; | ||
//~^ ERROR attributes cannot be applied to types | ||
|
||
let _: Bar<#[cfg(any())] 'static> = Bar(&123); | ||
//~^ ERROR attributes cannot be applied to generic arguments | ||
|
||
let _: Baz<#[cfg(any())] 42> = Baz(42); | ||
//~^ ERROR attributes cannot be applied to generic arguments | ||
|
||
let _: Foo<#[cfg(not(wrong))]String> = Foo(String::new()); | ||
//~^ ERROR attributes cannot be applied to generic arguments | ||
|
||
let _: Bar<#[cfg(any())] 'static> = Bar(&456); | ||
//~^ ERROR attributes cannot be applied to generic arguments | ||
|
||
let _generic: Box<#[attr] i32> = Box::new(1); | ||
//~^ ERROR attributes cannot be applied to generic arguments | ||
|
||
let _assignment: #[attr] i32 = *Box::new(1); | ||
//~^ ERROR attributes cannot be applied to types | ||
|
||
let _complex: Vec<#[derive(Debug)] String> = vec![]; | ||
//~^ ERROR attributes cannot be applied to generic arguments | ||
|
||
let _nested: Box<Vec<#[cfg(feature = "test")] u64>> = Box::new(vec![]); | ||
//~^ ERROR attributes cannot be applied to generic arguments | ||
} | ||
|
||
fn g() -> #[attr] i32 { 0 } | ||
//~^ ERROR attributes cannot be applied to types | ||
|
||
struct S { | ||
field: #[attr] i32, | ||
//~^ ERROR attributes cannot be applied to types | ||
field1: (#[attr] i32, i32), | ||
//~^ ERROR attributes cannot be applied to types | ||
} | ||
|
||
type Tuple = (#[attr] i32, String); | ||
//~^ ERROR attributes cannot be applied to types | ||
|
||
impl #[attr] S {} | ||
//~^ ERROR attributes cannot be applied to types |
Uh oh!
There was an error while loading. Please reload this page.