Skip to content

Commit a962bdb

Browse files
committed
Use #[rustc_paren_sugar] as a more extensible way of deciding when
paren sugar is legal.
1 parent 80c793c commit a962bdb

File tree

9 files changed

+41
-7
lines changed

9 files changed

+41
-7
lines changed

src/liballoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
#![feature(lang_items, unsafe_destructor)]
7171
#![feature(box_syntax)]
7272
#![feature(optin_builtin_traits)]
73+
#![feature(unboxed_closures)]
7374
#![allow(unknown_features)] #![feature(int_uint)]
7475
#![feature(core)]
7576
#![feature(hash)]

src/libcore/ops.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1166,6 +1166,7 @@ impl<F,A,R> FnOnce<A,R> for F
11661166
#[unstable(feature = "core",
11671167
reason = "uncertain about variadic generics, input versus associated types")]
11681168
#[cfg(not(stage0))]
1169+
#[rustc_paren_sugar]
11691170
pub trait Fn<Args> {
11701171
type Output;
11711172

@@ -1178,6 +1179,7 @@ pub trait Fn<Args> {
11781179
#[unstable(feature = "core",
11791180
reason = "uncertain about variadic generics, input versus associated types")]
11801181
#[cfg(not(stage0))]
1182+
#[rustc_paren_sugar]
11811183
pub trait FnMut<Args> {
11821184
type Output;
11831185

@@ -1190,6 +1192,7 @@ pub trait FnMut<Args> {
11901192
#[unstable(feature = "core",
11911193
reason = "uncertain about variadic generics, input versus associated types")]
11921194
#[cfg(not(stage0))]
1195+
#[rustc_paren_sugar]
11931196
pub trait FnOnce<Args> {
11941197
type Output;
11951198

src/librustc/lint/builtin.rs

+1
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,7 @@ impl LintPass for UnusedAttributes {
670670
// FIXME: #19470 this shouldn't be needed forever
671671
"old_orphan_check",
672672
"old_impl_check",
673+
"rustc_paren_sugar", // FIXME: #18101 temporary unboxed closure hack
673674
];
674675

675676
static CRATE_ATTRS: &'static [&'static str] = &[

src/librustc/metadata/common.rs

+2
Original file line numberDiff line numberDiff line change
@@ -265,3 +265,5 @@ pub const tag_polarity: uint = 0xb4;
265265
pub const tag_macro_defs: uint = 0xb5;
266266
pub const tag_macro_def: uint = 0xb6;
267267
pub const tag_macro_def_body: uint = 0xb7;
268+
269+
pub const tag_paren_sugar: uint = 0xb8;

src/librustc/metadata/decoder.rs

+7
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,11 @@ fn parse_unsafety(item_doc: rbml::Doc) -> ast::Unsafety {
371371
}
372372
}
373373

374+
fn parse_paren_sugar(item_doc: rbml::Doc) -> bool {
375+
let paren_sugar_doc = reader::get_doc(item_doc, tag_paren_sugar);
376+
reader::doc_as_u8(paren_sugar_doc) != 0
377+
}
378+
374379
fn parse_polarity(item_doc: rbml::Doc) -> ast::ImplPolarity {
375380
let polarity_doc = reader::get_doc(item_doc, tag_polarity);
376381
if reader::doc_as_u8(polarity_doc) != 0 {
@@ -400,8 +405,10 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
400405
let bounds = trait_def_bounds(item_doc, tcx, cdata);
401406
let unsafety = parse_unsafety(item_doc);
402407
let associated_type_names = parse_associated_type_names(item_doc);
408+
let paren_sugar = parse_paren_sugar(item_doc);
403409

404410
ty::TraitDef {
411+
paren_sugar: paren_sugar,
405412
unsafety: unsafety,
406413
generics: generics,
407414
bounds: bounds,

src/librustc/metadata/encoder.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
13171317
encode_item_variances(rbml_w, ecx, item.id);
13181318
let trait_def = ty::lookup_trait_def(tcx, def_id);
13191319
encode_unsafety(rbml_w, trait_def.unsafety);
1320+
encode_paren_sugar(rbml_w, trait_def.paren_sugar);
13201321
encode_associated_type_names(rbml_w, trait_def.associated_type_names.as_slice());
13211322
encode_generics(rbml_w, ecx, &trait_def.generics, tag_item_generics);
13221323
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) {
16971698
rbml_w.wr_tagged_u8(tag_unsafety, byte);
16981699
}
16991700

1701+
fn encode_paren_sugar(rbml_w: &mut Encoder, paren_sugar: bool) {
1702+
let byte: u8 = if paren_sugar {1} else {0};
1703+
rbml_w.wr_tagged_u8(tag_paren_sugar, byte);
1704+
}
1705+
17001706
fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[ast::Name]) {
17011707
rbml_w.start_tag(tag_associated_type_names);
17021708
for &name in names.iter() {

src/librustc/middle/ty.rs

+6
Original file line numberDiff line numberDiff line change
@@ -2221,6 +2221,12 @@ pub struct TypeScheme<'tcx> {
22212221
pub struct TraitDef<'tcx> {
22222222
pub unsafety: ast::Unsafety,
22232223

2224+
/// If `true`, then this trait had the `#[rustc_paren_sugar]`
2225+
/// attribute, indicating that it should be used with `Foo()`
2226+
/// sugar. This is a temporary thing -- eventually any trait wil
2227+
/// be usable with the sugar (or without it).
2228+
pub paren_sugar: bool,
2229+
22242230
/// Generic type definitions. Note that `Self` is listed in here
22252231
/// as having a single bound, the trait itself (e.g., in the trait
22262232
/// `Eq`, there is a single bound `Self : Eq`). This is so that

src/librustc_typeck/astconv.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -614,11 +614,9 @@ fn ast_path_to_trait_ref<'a,'tcx>(
614614

615615
let (regions, types, assoc_bindings) = match path.segments.last().unwrap().parameters {
616616
ast::AngleBracketedParameters(ref data) => {
617-
// For now, require that parenthetical notation be used
617+
// For now, require that parenthetical5D notation be used
618618
// only with `Fn()` etc.
619-
if !this.tcx().sess.features.borrow().unboxed_closures &&
620-
this.tcx().lang_items.fn_trait_kind(trait_def_id).is_some()
621-
{
619+
if !this.tcx().sess.features.borrow().unboxed_closures && trait_def.paren_sugar {
622620
span_err!(this.tcx().sess, path.span, E0215,
623621
"angle-bracket notation is not stable when \
624622
used with the `Fn` family of traits, use parentheses");
@@ -632,9 +630,7 @@ fn ast_path_to_trait_ref<'a,'tcx>(
632630
ast::ParenthesizedParameters(ref data) => {
633631
// For now, require that parenthetical notation be used
634632
// only with `Fn()` etc.
635-
if !this.tcx().sess.features.borrow().unboxed_closures &&
636-
this.tcx().lang_items.fn_trait_kind(trait_def_id).is_none()
637-
{
633+
if !this.tcx().sess.features.borrow().unboxed_closures && !trait_def.paren_sugar {
638634
span_err!(this.tcx().sess, path.span, E0216,
639635
"parenthetical notation is only stable when \
640636
used with the `Fn` family of traits");

src/librustc_typeck/collect.rs

+12
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,17 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
855855
}
856856
};
857857

858+
let paren_sugar = ty::has_attr(tcx, def_id, "rustc_paren_sugar");
859+
if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
860+
ccx.tcx.sess.span_err(
861+
it.span,
862+
"the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
863+
which traits can use parenthetical notation");
864+
span_help!(ccx.tcx.sess, it.span,
865+
"add `#![feature(unboxed_closures)]` to \
866+
the crate attributes to use it");
867+
}
868+
858869
let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
859870

860871
let ty_generics = ty_generics_for_trait(ccx,
@@ -887,6 +898,7 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
887898
});
888899

889900
let trait_def = Rc::new(ty::TraitDef {
901+
paren_sugar: paren_sugar,
890902
unsafety: unsafety,
891903
generics: ty_generics,
892904
bounds: bounds,

0 commit comments

Comments
 (0)