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:
Mazdak Farrokhzad 2019-06-19 17:34:36 +02:00 committed by GitHub
commit 7b3984b21b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 111 additions and 106 deletions

View File

@ -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> {

View File

@ -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(&param);
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) {

View 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>();
}

View File

@ -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`.

View File

@ -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() {}

View File

@ -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`.