Use #[rustc_paren_sugar]
as a more extensible way of deciding when
paren sugar is legal.
This commit is contained in:
parent
80c793c1d3
commit
a962bdb3da
9 changed files with 41 additions and 7 deletions
|
@ -70,6 +70,7 @@
|
||||||
#![feature(lang_items, unsafe_destructor)]
|
#![feature(lang_items, unsafe_destructor)]
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
#![feature(optin_builtin_traits)]
|
#![feature(optin_builtin_traits)]
|
||||||
|
#![feature(unboxed_closures)]
|
||||||
#![allow(unknown_features)] #![feature(int_uint)]
|
#![allow(unknown_features)] #![feature(int_uint)]
|
||||||
#![feature(core)]
|
#![feature(core)]
|
||||||
#![feature(hash)]
|
#![feature(hash)]
|
||||||
|
|
|
@ -1166,6 +1166,7 @@ impl<F,A,R> FnOnce<A,R> for F
|
||||||
#[unstable(feature = "core",
|
#[unstable(feature = "core",
|
||||||
reason = "uncertain about variadic generics, input versus associated types")]
|
reason = "uncertain about variadic generics, input versus associated types")]
|
||||||
#[cfg(not(stage0))]
|
#[cfg(not(stage0))]
|
||||||
|
#[rustc_paren_sugar]
|
||||||
pub trait Fn<Args> {
|
pub trait Fn<Args> {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
||||||
|
@ -1178,6 +1179,7 @@ pub trait Fn<Args> {
|
||||||
#[unstable(feature = "core",
|
#[unstable(feature = "core",
|
||||||
reason = "uncertain about variadic generics, input versus associated types")]
|
reason = "uncertain about variadic generics, input versus associated types")]
|
||||||
#[cfg(not(stage0))]
|
#[cfg(not(stage0))]
|
||||||
|
#[rustc_paren_sugar]
|
||||||
pub trait FnMut<Args> {
|
pub trait FnMut<Args> {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
||||||
|
@ -1190,6 +1192,7 @@ pub trait FnMut<Args> {
|
||||||
#[unstable(feature = "core",
|
#[unstable(feature = "core",
|
||||||
reason = "uncertain about variadic generics, input versus associated types")]
|
reason = "uncertain about variadic generics, input versus associated types")]
|
||||||
#[cfg(not(stage0))]
|
#[cfg(not(stage0))]
|
||||||
|
#[rustc_paren_sugar]
|
||||||
pub trait FnOnce<Args> {
|
pub trait FnOnce<Args> {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
||||||
|
|
|
@ -670,6 +670,7 @@ impl LintPass for UnusedAttributes {
|
||||||
// FIXME: #19470 this shouldn't be needed forever
|
// FIXME: #19470 this shouldn't be needed forever
|
||||||
"old_orphan_check",
|
"old_orphan_check",
|
||||||
"old_impl_check",
|
"old_impl_check",
|
||||||
|
"rustc_paren_sugar", // FIXME: #18101 temporary unboxed closure hack
|
||||||
];
|
];
|
||||||
|
|
||||||
static CRATE_ATTRS: &'static [&'static str] = &[
|
static CRATE_ATTRS: &'static [&'static str] = &[
|
||||||
|
|
|
@ -265,3 +265,5 @@ pub const tag_polarity: uint = 0xb4;
|
||||||
pub const tag_macro_defs: uint = 0xb5;
|
pub const tag_macro_defs: uint = 0xb5;
|
||||||
pub const tag_macro_def: uint = 0xb6;
|
pub const tag_macro_def: uint = 0xb6;
|
||||||
pub const tag_macro_def_body: uint = 0xb7;
|
pub const tag_macro_def_body: uint = 0xb7;
|
||||||
|
|
||||||
|
pub const tag_paren_sugar: uint = 0xb8;
|
||||||
|
|
|
@ -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 {
|
fn parse_polarity(item_doc: rbml::Doc) -> ast::ImplPolarity {
|
||||||
let polarity_doc = reader::get_doc(item_doc, tag_polarity);
|
let polarity_doc = reader::get_doc(item_doc, tag_polarity);
|
||||||
if reader::doc_as_u8(polarity_doc) != 0 {
|
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 bounds = trait_def_bounds(item_doc, tcx, cdata);
|
||||||
let unsafety = parse_unsafety(item_doc);
|
let unsafety = parse_unsafety(item_doc);
|
||||||
let associated_type_names = parse_associated_type_names(item_doc);
|
let associated_type_names = parse_associated_type_names(item_doc);
|
||||||
|
let paren_sugar = parse_paren_sugar(item_doc);
|
||||||
|
|
||||||
ty::TraitDef {
|
ty::TraitDef {
|
||||||
|
paren_sugar: paren_sugar,
|
||||||
unsafety: unsafety,
|
unsafety: unsafety,
|
||||||
generics: generics,
|
generics: generics,
|
||||||
bounds: bounds,
|
bounds: bounds,
|
||||||
|
|
|
@ -1317,6 +1317,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
||||||
encode_item_variances(rbml_w, ecx, item.id);
|
encode_item_variances(rbml_w, ecx, item.id);
|
||||||
let trait_def = ty::lookup_trait_def(tcx, def_id);
|
let trait_def = ty::lookup_trait_def(tcx, def_id);
|
||||||
encode_unsafety(rbml_w, trait_def.unsafety);
|
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_associated_type_names(rbml_w, trait_def.associated_type_names.as_slice());
|
||||||
encode_generics(rbml_w, ecx, &trait_def.generics, tag_item_generics);
|
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);
|
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);
|
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]) {
|
fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[ast::Name]) {
|
||||||
rbml_w.start_tag(tag_associated_type_names);
|
rbml_w.start_tag(tag_associated_type_names);
|
||||||
for &name in names.iter() {
|
for &name in names.iter() {
|
||||||
|
|
|
@ -2221,6 +2221,12 @@ pub struct TypeScheme<'tcx> {
|
||||||
pub struct TraitDef<'tcx> {
|
pub struct TraitDef<'tcx> {
|
||||||
pub unsafety: ast::Unsafety,
|
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
|
/// Generic type definitions. Note that `Self` is listed in here
|
||||||
/// as having a single bound, the trait itself (e.g., in the trait
|
/// 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
|
/// `Eq`, there is a single bound `Self : Eq`). This is so that
|
||||||
|
|
|
@ -614,11 +614,9 @@ fn ast_path_to_trait_ref<'a,'tcx>(
|
||||||
|
|
||||||
let (regions, types, assoc_bindings) = match path.segments.last().unwrap().parameters {
|
let (regions, types, assoc_bindings) = match path.segments.last().unwrap().parameters {
|
||||||
ast::AngleBracketedParameters(ref data) => {
|
ast::AngleBracketedParameters(ref data) => {
|
||||||
// For now, require that parenthetical notation be used
|
// For now, require that parenthetical5D notation be used
|
||||||
// only with `Fn()` etc.
|
// only with `Fn()` etc.
|
||||||
if !this.tcx().sess.features.borrow().unboxed_closures &&
|
if !this.tcx().sess.features.borrow().unboxed_closures && trait_def.paren_sugar {
|
||||||
this.tcx().lang_items.fn_trait_kind(trait_def_id).is_some()
|
|
||||||
{
|
|
||||||
span_err!(this.tcx().sess, path.span, E0215,
|
span_err!(this.tcx().sess, path.span, E0215,
|
||||||
"angle-bracket notation is not stable when \
|
"angle-bracket notation is not stable when \
|
||||||
used with the `Fn` family of traits, use parentheses");
|
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) => {
|
ast::ParenthesizedParameters(ref data) => {
|
||||||
// For now, require that parenthetical notation be used
|
// For now, require that parenthetical notation be used
|
||||||
// only with `Fn()` etc.
|
// only with `Fn()` etc.
|
||||||
if !this.tcx().sess.features.borrow().unboxed_closures &&
|
if !this.tcx().sess.features.borrow().unboxed_closures && !trait_def.paren_sugar {
|
||||||
this.tcx().lang_items.fn_trait_kind(trait_def_id).is_none()
|
|
||||||
{
|
|
||||||
span_err!(this.tcx().sess, path.span, E0216,
|
span_err!(this.tcx().sess, path.span, E0216,
|
||||||
"parenthetical notation is only stable when \
|
"parenthetical notation is only stable when \
|
||||||
used with the `Fn` family of traits");
|
used with the `Fn` family of traits");
|
||||||
|
|
|
@ -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 substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
|
||||||
|
|
||||||
let ty_generics = ty_generics_for_trait(ccx,
|
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 {
|
let trait_def = Rc::new(ty::TraitDef {
|
||||||
|
paren_sugar: paren_sugar,
|
||||||
unsafety: unsafety,
|
unsafety: unsafety,
|
||||||
generics: ty_generics,
|
generics: ty_generics,
|
||||||
bounds: bounds,
|
bounds: bounds,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue