Rollup merge of #61547 - petrochenkov:cfgen, r=Centril
Support `cfg` and `cfg_attr` on generic parameters `cfg` attributes are supported in all other positions where attributes are accepted at all. They were previously prohibited in https://github.com/rust-lang/rust/pull/51283 because they weren't implemented correctly before that and were simply ignored.
This commit is contained in:
commit
7b3984b21b
@ -240,6 +240,10 @@ pub fn configure_foreign_mod(&mut self, foreign_mod: &mut ast::ForeignMod) {
|
||||
items.flat_map_in_place(|item| self.configure(item));
|
||||
}
|
||||
|
||||
pub fn configure_generic_params(&mut self, params: &mut Vec<ast::GenericParam>) {
|
||||
params.flat_map_in_place(|param| self.configure(param));
|
||||
}
|
||||
|
||||
fn configure_variant_data(&mut self, vdata: &mut ast::VariantData) {
|
||||
match vdata {
|
||||
ast::VariantData::Struct(fields, ..) | ast::VariantData::Tuple(fields, _) =>
|
||||
@ -301,22 +305,6 @@ pub fn configure_pat(&mut self, pat: &mut P<ast::Pat>) {
|
||||
pub fn configure_fn_decl(&mut self, fn_decl: &mut ast::FnDecl) {
|
||||
fn_decl.inputs.flat_map_in_place(|arg| self.configure(arg));
|
||||
}
|
||||
|
||||
/// Denies `#[cfg]` on generic parameters until we decide what to do with it.
|
||||
/// See issue #51279.
|
||||
pub fn disallow_cfg_on_generic_param(&mut self, param: &ast::GenericParam) {
|
||||
for attr in param.attrs() {
|
||||
let offending_attr = if attr.check_name(sym::cfg) {
|
||||
"cfg"
|
||||
} else if attr.check_name(sym::cfg_attr) {
|
||||
"cfg_attr"
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
let msg = format!("#[{}] cannot be applied on a generic parameter", offending_attr);
|
||||
self.sess.span_diagnostic.span_err(attr.span, &msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> MutVisitor for StripUnconfigured<'a> {
|
||||
|
@ -1329,9 +1329,9 @@ fn visit_item_kind(&mut self, item: &mut ast::ItemKind) {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_generic_param(&mut self, param: &mut ast::GenericParam) {
|
||||
self.cfg.disallow_cfg_on_generic_param(¶m);
|
||||
noop_visit_generic_param(param, self)
|
||||
fn visit_generic_params(&mut self, params: &mut Vec<ast::GenericParam>) {
|
||||
self.cfg.configure_generic_params(params);
|
||||
noop_visit_generic_params(params, self);
|
||||
}
|
||||
|
||||
fn visit_attribute(&mut self, at: &mut ast::Attribute) {
|
||||
|
38
src/test/ui/conditional-compilation/cfg-generic-params.rs
Normal file
38
src/test/ui/conditional-compilation/cfg-generic-params.rs
Normal file
@ -0,0 +1,38 @@
|
||||
// compile-flags:--cfg yes
|
||||
|
||||
fn f_lt<#[cfg(yes)] 'a: 'a, #[cfg(no)] T>() {}
|
||||
fn f_ty<#[cfg(no)] 'a: 'a, #[cfg(yes)] T>() {}
|
||||
|
||||
type FnGood = for<#[cfg(yes)] 'a, #[cfg(no)] T> fn(); // OK
|
||||
type FnBad = for<#[cfg(no)] 'a, #[cfg(yes)] T> fn();
|
||||
//~^ ERROR only lifetime parameters can be used in this context
|
||||
|
||||
type PolyGood = dyn for<#[cfg(yes)] 'a, #[cfg(no)] T> Copy; // OK
|
||||
type PolyBad = dyn for<#[cfg(no)] 'a, #[cfg(yes)] T> Copy;
|
||||
//~^ ERROR only lifetime parameters can be used in this context
|
||||
|
||||
struct WhereGood where for<#[cfg(yes)] 'a, #[cfg(no)] T> u8: Copy; // OK
|
||||
struct WhereBad where for<#[cfg(no)] 'a, #[cfg(yes)] T> u8: Copy;
|
||||
//~^ ERROR only lifetime parameters can be used in this context
|
||||
|
||||
fn f_lt_no<#[cfg_attr(no, unknown)] 'a>() {} // OK
|
||||
fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {} //~ ERROR attribute `unknown` is currently unknown
|
||||
fn f_ty_no<#[cfg_attr(no, unknown)] T>() {} // OK
|
||||
fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {} //~ ERROR attribute `unknown` is currently unknown
|
||||
|
||||
type FnNo = for<#[cfg_attr(no, unknown)] 'a> fn(); // OK
|
||||
type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn();
|
||||
//~^ ERROR attribute `unknown` is currently unknown
|
||||
|
||||
type PolyNo = dyn for<#[cfg_attr(no, unknown)] 'a> Copy; // OK
|
||||
type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy;
|
||||
//~^ ERROR attribute `unknown` is currently unknown
|
||||
|
||||
struct WhereNo where for<#[cfg_attr(no, unknown)] 'a> u8: Copy; // OK
|
||||
struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy;
|
||||
//~^ ERROR attribute `unknown` is currently unknown
|
||||
|
||||
fn main() {
|
||||
f_lt::<'static>();
|
||||
f_ty::<u8>();
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
error: only lifetime parameters can be used in this context
|
||||
--> $DIR/cfg-generic-params.rs:7:45
|
||||
|
|
||||
LL | type FnBad = for<#[cfg(no)] 'a, #[cfg(yes)] T> fn();
|
||||
| ^
|
||||
|
||||
error: only lifetime parameters can be used in this context
|
||||
--> $DIR/cfg-generic-params.rs:11:51
|
||||
|
|
||||
LL | type PolyBad = dyn for<#[cfg(no)] 'a, #[cfg(yes)] T> Copy;
|
||||
| ^
|
||||
|
||||
error: only lifetime parameters can be used in this context
|
||||
--> $DIR/cfg-generic-params.rs:15:54
|
||||
|
|
||||
LL | struct WhereBad where for<#[cfg(no)] 'a, #[cfg(yes)] T> u8: Copy;
|
||||
| ^
|
||||
|
||||
error[E0658]: The attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future
|
||||
--> $DIR/cfg-generic-params.rs:19:29
|
||||
|
|
||||
LL | fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {}
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
|
||||
= help: add #![feature(custom_attribute)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: The attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future
|
||||
--> $DIR/cfg-generic-params.rs:21:29
|
||||
|
|
||||
LL | fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {}
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
|
||||
= help: add #![feature(custom_attribute)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: The attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future
|
||||
--> $DIR/cfg-generic-params.rs:24:34
|
||||
|
|
||||
LL | type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn();
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
|
||||
= help: add #![feature(custom_attribute)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: The attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future
|
||||
--> $DIR/cfg-generic-params.rs:28:40
|
||||
|
|
||||
LL | type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy;
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
|
||||
= help: add #![feature(custom_attribute)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: The attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future
|
||||
--> $DIR/cfg-generic-params.rs:32:43
|
||||
|
|
||||
LL | struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy;
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
|
||||
= help: add #![feature(custom_attribute)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -1,27 +0,0 @@
|
||||
pub struct X<#[cfg(none)] 'a, #[cfg(none)] T>(&'a T);
|
||||
//~^ ERROR #[cfg] cannot be applied on a generic parameter
|
||||
//~^^ ERROR #[cfg] cannot be applied on a generic parameter
|
||||
|
||||
impl<#[cfg(none)] 'a, #[cfg(none)] T> X<'a, T> {}
|
||||
//~^ ERROR #[cfg] cannot be applied on a generic parameter
|
||||
//~^^ ERROR #[cfg] cannot be applied on a generic parameter
|
||||
|
||||
pub fn f<#[cfg(none)] 'a, #[cfg(none)] T>(_: &'a T) {}
|
||||
//~^ ERROR #[cfg] cannot be applied on a generic parameter
|
||||
//~^^ ERROR #[cfg] cannot be applied on a generic parameter
|
||||
|
||||
#[cfg(none)]
|
||||
pub struct Y<#[cfg(none)] T>(T); // shouldn't care when the entire item is stripped out
|
||||
|
||||
struct M<T>(*const T);
|
||||
|
||||
impl<#[cfg_attr(none, may_dangle)] T> Drop for M<T> {
|
||||
//~^ ERROR #[cfg_attr] cannot be applied on a generic parameter
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
type Z<#[ignored] 'a, #[cfg(none)] T> = X<'a, T>;
|
||||
//~^ ERROR #[cfg] cannot be applied on a generic parameter
|
||||
//~| ERROR attribute `ignored` is currently unknown to the compiler
|
||||
|
||||
fn main() {}
|
@ -1,60 +0,0 @@
|
||||
error: #[cfg] cannot be applied on a generic parameter
|
||||
--> $DIR/issue-51279.rs:1:14
|
||||
|
|
||||
LL | pub struct X<#[cfg(none)] 'a, #[cfg(none)] T>(&'a T);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: #[cfg] cannot be applied on a generic parameter
|
||||
--> $DIR/issue-51279.rs:1:31
|
||||
|
|
||||
LL | pub struct X<#[cfg(none)] 'a, #[cfg(none)] T>(&'a T);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: #[cfg] cannot be applied on a generic parameter
|
||||
--> $DIR/issue-51279.rs:5:6
|
||||
|
|
||||
LL | impl<#[cfg(none)] 'a, #[cfg(none)] T> X<'a, T> {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: #[cfg] cannot be applied on a generic parameter
|
||||
--> $DIR/issue-51279.rs:5:23
|
||||
|
|
||||
LL | impl<#[cfg(none)] 'a, #[cfg(none)] T> X<'a, T> {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: #[cfg] cannot be applied on a generic parameter
|
||||
--> $DIR/issue-51279.rs:9:10
|
||||
|
|
||||
LL | pub fn f<#[cfg(none)] 'a, #[cfg(none)] T>(_: &'a T) {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: #[cfg] cannot be applied on a generic parameter
|
||||
--> $DIR/issue-51279.rs:9:27
|
||||
|
|
||||
LL | pub fn f<#[cfg(none)] 'a, #[cfg(none)] T>(_: &'a T) {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: #[cfg_attr] cannot be applied on a generic parameter
|
||||
--> $DIR/issue-51279.rs:18:6
|
||||
|
|
||||
LL | impl<#[cfg_attr(none, may_dangle)] T> Drop for M<T> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: #[cfg] cannot be applied on a generic parameter
|
||||
--> $DIR/issue-51279.rs:23:23
|
||||
|
|
||||
LL | type Z<#[ignored] 'a, #[cfg(none)] T> = X<'a, T>;
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error[E0658]: The attribute `ignored` is currently unknown to the compiler and may have meaning added to it in the future
|
||||
--> $DIR/issue-51279.rs:23:8
|
||||
|
|
||||
LL | type Z<#[ignored] 'a, #[cfg(none)] T> = X<'a, T>;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
|
||||
= help: add #![feature(custom_attribute)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
Loading…
Reference in New Issue
Block a user