Skip to content

Commit

Permalink
Rollup merge of rust-lang#61547 - petrochenkov:cfgen, r=Centril
Browse files Browse the repository at this point in the history
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 rust-lang#51283 because they weren't implemented correctly before that and were simply ignored.
  • Loading branch information
Centril authored Jun 19, 2019
2 parents 3f34659 + 0b58bb3 commit 6820f2e
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 106 deletions.
20 changes: 4 additions & 16 deletions src/libsyntax/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@ impl<'a> StripUnconfigured<'a> {
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, _) =>
Expand Down Expand Up @@ -301,22 +305,6 @@ impl<'a> StripUnconfigured<'a> {
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> {
Expand Down
6 changes: 3 additions & 3 deletions src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1329,9 +1329,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
}
}

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) {
Expand Down
38 changes: 38 additions & 0 deletions src/test/ui/conditional-compilation/cfg-generic-params.rs
Original file line number Diff line number Diff line change
@@ -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>();
}
66 changes: 66 additions & 0 deletions src/test/ui/conditional-compilation/cfg-generic-params.stderr
Original file line number Diff line number Diff line change
@@ -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`.
27 changes: 0 additions & 27 deletions src/test/ui/issues/issue-51279.rs

This file was deleted.

60 changes: 0 additions & 60 deletions src/test/ui/issues/issue-51279.stderr

This file was deleted.

0 comments on commit 6820f2e

Please sign in to comment.