]> git.lizzy.rs Git - rust.git/commitdiff
Use `#[rustc_paren_sugar]` as a more extensible way of deciding when
authorNiko Matsakis <niko@alum.mit.edu>
Mon, 26 Jan 2015 19:39:58 +0000 (14:39 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Fri, 30 Jan 2015 10:57:57 +0000 (05:57 -0500)
paren sugar is legal.

src/liballoc/lib.rs
src/libcore/ops.rs
src/librustc/lint/builtin.rs
src/librustc/metadata/common.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/middle/ty.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/collect.rs

index f807d8d12a6b56d9dba2e8675e94dc28add38212..8960667fdfa861481f82f4d721c9a6ff5ee9f925 100644 (file)
@@ -70,6 +70,7 @@
 #![feature(lang_items, unsafe_destructor)]
 #![feature(box_syntax)]
 #![feature(optin_builtin_traits)]
+#![feature(unboxed_closures)]
 #![allow(unknown_features)] #![feature(int_uint)]
 #![feature(core)]
 #![feature(hash)]
index 55ff3eb4d062d8bc7be2967c379931343591c5ff..80232764ed42f392971c17c7a437a357b5847f72 100644 (file)
@@ -1166,6 +1166,7 @@ extern "rust-call" fn call_once(mut self, args: A) -> R {
 #[unstable(feature = "core",
            reason = "uncertain about variadic generics, input versus associated types")]
 #[cfg(not(stage0))]
+#[rustc_paren_sugar]
 pub trait Fn<Args> {
     type Output;
 
@@ -1178,6 +1179,7 @@ pub trait Fn<Args> {
 #[unstable(feature = "core",
            reason = "uncertain about variadic generics, input versus associated types")]
 #[cfg(not(stage0))]
+#[rustc_paren_sugar]
 pub trait FnMut<Args> {
     type Output;
 
@@ -1190,6 +1192,7 @@ pub trait FnMut<Args> {
 #[unstable(feature = "core",
            reason = "uncertain about variadic generics, input versus associated types")]
 #[cfg(not(stage0))]
+#[rustc_paren_sugar]
 pub trait FnOnce<Args> {
     type Output;
 
index f13814527cdfd3a6ddb58b691839c85753a34814..ee7c0ee894fc7b927200ca7744e81ab010c0f4a5 100644 (file)
@@ -670,6 +670,7 @@ fn check_attribute(&mut self, cx: &Context, attr: &ast::Attribute) {
             // FIXME: #19470 this shouldn't be needed forever
             "old_orphan_check",
             "old_impl_check",
+            "rustc_paren_sugar", // FIXME: #18101 temporary unboxed closure hack
         ];
 
         static CRATE_ATTRS: &'static [&'static str] = &[
index 6c1a8a6f54bbf3fc7b595fef5f6800c2d35cd71d..242ab630a20ef424a8eaef8ebd506b9d12dc9da7 100644 (file)
@@ -265,3 +265,5 @@ pub struct LinkMeta {
 pub const tag_macro_defs: uint = 0xb5;
 pub const tag_macro_def: uint = 0xb6;
 pub const tag_macro_def_body: uint = 0xb7;
+
+pub const tag_paren_sugar: uint = 0xb8;
index 933fd873aeb7a06d4d3a6b9936c0ee06cc46cffa..93ca42e9a2872c41fb2d5b64ad946c39c49b8d8c 100644 (file)
@@ -371,6 +371,11 @@ fn parse_unsafety(item_doc: rbml::Doc) -> ast::Unsafety {
     }
 }
 
+fn parse_paren_sugar(item_doc: rbml::Doc) -> bool {
+    let paren_sugar_doc = reader::get_doc(item_doc, tag_paren_sugar);
+    reader::doc_as_u8(paren_sugar_doc) != 0
+}
+
 fn parse_polarity(item_doc: rbml::Doc) -> ast::ImplPolarity {
     let polarity_doc = reader::get_doc(item_doc, tag_polarity);
     if reader::doc_as_u8(polarity_doc) != 0 {
@@ -400,8 +405,10 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
     let bounds = trait_def_bounds(item_doc, tcx, cdata);
     let unsafety = parse_unsafety(item_doc);
     let associated_type_names = parse_associated_type_names(item_doc);
+    let paren_sugar = parse_paren_sugar(item_doc);
 
     ty::TraitDef {
+        paren_sugar: paren_sugar,
         unsafety: unsafety,
         generics: generics,
         bounds: bounds,
index 13dc9397afc0f011d9f18fe98dbcc29d82f0b953..6767f77de84bb61ed017a3b2874f6ed500be4209 100644 (file)
@@ -1317,6 +1317,7 @@ fn add_to_index(item: &ast::Item, rbml_w: &Encoder,
         encode_item_variances(rbml_w, ecx, item.id);
         let trait_def = ty::lookup_trait_def(tcx, def_id);
         encode_unsafety(rbml_w, trait_def.unsafety);
+        encode_paren_sugar(rbml_w, trait_def.paren_sugar);
         encode_associated_type_names(rbml_w, trait_def.associated_type_names.as_slice());
         encode_generics(rbml_w, ecx, &trait_def.generics, tag_item_generics);
         encode_trait_ref(rbml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
@@ -1697,6 +1698,11 @@ fn encode_unsafety(rbml_w: &mut Encoder, unsafety: ast::Unsafety) {
     rbml_w.wr_tagged_u8(tag_unsafety, byte);
 }
 
+fn encode_paren_sugar(rbml_w: &mut Encoder, paren_sugar: bool) {
+    let byte: u8 = if paren_sugar {1} else {0};
+    rbml_w.wr_tagged_u8(tag_paren_sugar, byte);
+}
+
 fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[ast::Name]) {
     rbml_w.start_tag(tag_associated_type_names);
     for &name in names.iter() {
index 9958d015a8cd3f31fc61c840ce4b3395a6c91dae..425acbae483fe4824245056986c1bb80794e93d7 100644 (file)
@@ -2221,6 +2221,12 @@ pub struct TypeScheme<'tcx> {
 pub struct TraitDef<'tcx> {
     pub unsafety: ast::Unsafety,
 
+    /// If `true`, then this trait had the `#[rustc_paren_sugar]`
+    /// attribute, indicating that it should be used with `Foo()`
+    /// sugar. This is a temporary thing -- eventually any trait wil
+    /// be usable with the sugar (or without it).
+    pub paren_sugar: bool,
+
     /// Generic type definitions. Note that `Self` is listed in here
     /// as having a single bound, the trait itself (e.g., in the trait
     /// `Eq`, there is a single bound `Self : Eq`). This is so that
index a382cfca0bd899e73b25c1e185dfb984e78dc774..350227c6662433757bbede36c59a63a9c0a06d24 100644 (file)
@@ -614,11 +614,9 @@ fn ast_path_to_trait_ref<'a,'tcx>(
 
     let (regions, types, assoc_bindings) = match path.segments.last().unwrap().parameters {
         ast::AngleBracketedParameters(ref data) => {
-            // For now, require that parenthetical notation be used
+            // For now, require that parenthetical5D notation be used
             // only with `Fn()` etc.
-            if !this.tcx().sess.features.borrow().unboxed_closures &&
-                this.tcx().lang_items.fn_trait_kind(trait_def_id).is_some()
-            {
+            if !this.tcx().sess.features.borrow().unboxed_closures && trait_def.paren_sugar {
                 span_err!(this.tcx().sess, path.span, E0215,
                                          "angle-bracket notation is not stable when \
                                          used with the `Fn` family of traits, use parentheses");
@@ -632,9 +630,7 @@ fn ast_path_to_trait_ref<'a,'tcx>(
         ast::ParenthesizedParameters(ref data) => {
             // For now, require that parenthetical notation be used
             // only with `Fn()` etc.
-            if !this.tcx().sess.features.borrow().unboxed_closures &&
-                this.tcx().lang_items.fn_trait_kind(trait_def_id).is_none()
-            {
+            if !this.tcx().sess.features.borrow().unboxed_closures && !trait_def.paren_sugar {
                 span_err!(this.tcx().sess, path.span, E0216,
                                          "parenthetical notation is only stable when \
                                          used with the `Fn` family of traits");
index 8158b8da86dfd6f149da7c5b76c95dae73faa269..ed33ddd458a54223de475475d659c74b577454e6 100644 (file)
@@ -855,6 +855,17 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
         }
     };
 
+    let paren_sugar = ty::has_attr(tcx, def_id, "rustc_paren_sugar");
+    if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
+        ccx.tcx.sess.span_err(
+            it.span,
+            "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
+             which traits can use parenthetical notation");
+        span_help!(ccx.tcx.sess, it.span,
+                   "add `#![feature(unboxed_closures)]` to \
+                    the crate attributes to use it");
+    }
+
     let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
 
     let ty_generics = ty_generics_for_trait(ccx,
@@ -887,6 +898,7 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
     });
 
     let trait_def = Rc::new(ty::TraitDef {
+        paren_sugar: paren_sugar,
         unsafety: unsafety,
         generics: ty_generics,
         bounds: bounds,