about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-10-04 06:48:13 +0000
committerbors <bors@rust-lang.org>2018-10-04 06:48:13 +0000
commit088fc7384c1ac3f7670d66880c7dcc0ec9160c79 (patch)
treea904b7f1880e2ec018f5dff0ddbde98f9e7a1de4 /src/libsyntax
parentc67ea54d4466f1c082f72b194c100bb4954449e6 (diff)
parentc793391e6d04106df57a4f431c7deeb4258a0592 (diff)
downloadrust-088fc7384c1ac3f7670d66880c7dcc0ec9160c79.tar.gz
rust-088fc7384c1ac3f7670d66880c7dcc0ec9160c79.zip
Auto merge of #53851 - oli-obk:local_promotion, r=eddyb
Limit the promotion of const fns to the libstd and the `rustc_promotable` attribute

There are so many questions around promoting const fn calls... it seems saner to try to limit automatic promotion to const fns which were explicitly opted in for promotion.

I added the attribute to all public stable const fns that were already promotable (e.g. not Cell::new) in order to not cause any breakage

r? @eddyb

cc @nikomatsakis
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/attr/builtin.rs23
-rw-r--r--src/libsyntax/diagnostic_list.rs1
2 files changed, 23 insertions, 1 deletions
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
index 5fc9c5578e1..f1cec422420 100644
--- a/src/libsyntax/attr/builtin.rs
+++ b/src/libsyntax/attr/builtin.rs
@@ -112,6 +112,8 @@ pub struct Stability {
     /// `Some` contains the feature gate required to be able to use the function
     /// as const fn
     pub const_stability: Option<Symbol>,
+    /// whether the function has a `#[rustc_promotable]` attribute
+    pub promotable: bool,
 }
 
 /// The available stability levels.
@@ -176,6 +178,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
     let mut stab: Option<Stability> = None;
     let mut rustc_depr: Option<RustcDeprecation> = None;
     let mut rustc_const_unstable: Option<Symbol> = None;
+    let mut promotable = false;
 
     'outer: for attr in attrs_iter {
         if ![
@@ -183,6 +186,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
             "rustc_const_unstable",
             "unstable",
             "stable",
+            "rustc_promotable",
         ].iter().any(|&s| attr.path == s) {
             continue // not a stability level
         }
@@ -190,8 +194,12 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
         mark_used(attr);
 
         let meta = attr.meta();
+
+        if attr.path == "rustc_promotable" {
+            promotable = true;
+        }
         // attributes with data
-        if let Some(MetaItem { node: MetaItemKind::List(ref metas), .. }) = meta {
+        else if let Some(MetaItem { node: MetaItemKind::List(ref metas), .. }) = meta {
             let meta = meta.as_ref().unwrap();
             let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
                 if item.is_some() {
@@ -329,6 +337,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
                                 feature,
                                 rustc_depr: None,
                                 const_stability: None,
+                                promotable: false,
                             })
                         }
                         (None, _, _) => {
@@ -378,6 +387,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
                                 feature,
                                 rustc_depr: None,
                                 const_stability: None,
+                                promotable: false,
                             })
                         }
                         (None, _) => {
@@ -420,6 +430,17 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
         }
     }
 
+    // Merge the const-unstable info into the stability info
+    if promotable {
+        if let Some(ref mut stab) = stab {
+            stab.promotable = true;
+        } else {
+            span_err!(diagnostic, item_sp, E0717,
+                      "rustc_promotable attribute must be paired with \
+                       either stable or unstable attribute");
+        }
+    }
+
     stab
 }
 
diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs
index 23ce7fc6a65..5155ebbe19d 100644
--- a/src/libsyntax/diagnostic_list.rs
+++ b/src/libsyntax/diagnostic_list.rs
@@ -413,4 +413,5 @@ register_diagnostics! {
     E0694, // an unknown tool name found in scoped attributes
     E0703, // invalid ABI
     E0704, // incorrect visibility restriction
+    E0717, // rustc_promotable without stability attribute
 }