diff options
| author | bors <bors@rust-lang.org> | 2017-09-21 00:35:33 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-09-21 00:35:33 +0000 |
| commit | e2504cfc7615b9247d4546672e31a9803f4b88ba (patch) | |
| tree | b6700e23d1a39a841a02491e8f7e2dee0a2e12c7 /src/libsyntax | |
| parent | 870483a57f9e3e1daee6543a4ace2cf875b74541 (diff) | |
| parent | 3fa3fe01b65ec4dde20c66c6bedcd28e2f83f8b6 (diff) | |
| download | rust-e2504cfc7615b9247d4546672e31a9803f4b88ba.tar.gz rust-e2504cfc7615b9247d4546672e31a9803f4b88ba.zip | |
Auto merge of #44551 - scalexm:copy-clone-closures, r=arielb1
Implement `Copy`/`Clone` for closures Implement RFC [#2132](https://github.com/rust-lang/rfcs/pull/2132) (tracking issue: #44490). NB: I'm not totally sure about the whole feature gates thing, that's my first PR of this kind...
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/attr.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 31 |
2 files changed, 41 insertions, 4 deletions
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 36ab3737f38..b1f796084df 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -500,6 +500,20 @@ pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str) -> Option<S .and_then(|at| at.value_str()) } +/// Check if `attrs` contains an attribute like `#![feature(feature_name)]`. +/// This will not perform any "sanity checks" on the form of the attributes. +pub fn contains_feature_attr(attrs: &[Attribute], feature_name: &str) -> bool { + attrs.iter().any(|item| { + item.check_name("feature") && + item.meta_item_list().map(|list| { + list.iter().any(|mi| { + mi.word().map(|w| w.name() == feature_name) + .unwrap_or(false) + }) + }).unwrap_or(false) + }) +} + /* Higher-level applications */ pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index ae0dd872963..6560943a932 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -385,6 +385,10 @@ declare_features! ( // allow '|' at beginning of match arms (RFC 1925) (active, match_beginning_vert, "1.21.0", Some(44101)), + + // Copy/Clone closures (RFC 2132) + (active, clone_closures, "1.22.0", Some(44490)), + (active, copy_closures, "1.22.0", Some(44490)), ); declare_features! ( @@ -1573,7 +1577,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute]) -> Features { let mut features = Features::new(); - let mut feature_checker = MutexFeatureChecker::default(); + let mut feature_checker = FeatureChecker::default(); for attr in krate_attrs { if !attr.check_name("feature") { @@ -1622,14 +1626,16 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute]) -> F features } -// A collector for mutually-exclusive features and their flag spans +/// A collector for mutually exclusive and interdependent features and their flag spans. #[derive(Default)] -struct MutexFeatureChecker { +struct FeatureChecker { proc_macro: Option<Span>, custom_attribute: Option<Span>, + copy_closures: Option<Span>, + clone_closures: Option<Span>, } -impl MutexFeatureChecker { +impl FeatureChecker { // If this method turns out to be a hotspot due to branching, // the branching can be eliminated by modifying `set!()` to set these spans // only for the features that need to be checked for mutual exclusion. @@ -1642,6 +1648,14 @@ impl MutexFeatureChecker { if features.custom_attribute { self.custom_attribute = self.custom_attribute.or(Some(span)); } + + if features.copy_closures { + self.copy_closures = self.copy_closures.or(Some(span)); + } + + if features.clone_closures { + self.clone_closures = self.clone_closures.or(Some(span)); + } } fn check(self, handler: &Handler) { @@ -1653,6 +1667,15 @@ impl MutexFeatureChecker { panic!(FatalError); } + + if let (Some(span), None) = (self.copy_closures, self.clone_closures) { + handler.struct_span_err(span, "`#![feature(copy_closures)]` can only be used with \ + `#![feature(clone_closures)]`") + .span_note(span, "`#![feature(copy_closures)]` declared here") + .emit(); + + panic!(FatalError); + } } } |
