encode_stability(rbml_w, stab);
rbml_w.end_tag();
}
- ast::ItemFn(ref decl, _, _, ref generics, _) => {
+ ast::ItemFn(ref decl, _, _, _, ref generics, _) => {
add_to_index(item, rbml_w, index);
rbml_w.start_tag(tag_items_data_item);
encode_def_id(rbml_w, def_id);
for id in ecx.reachable {
if let Some(ast_map::NodeItem(i)) = ecx.tcx.map.find(*id) {
- if let ast::ItemFn(_, _, abi, ref generics, _) = i.node {
+ if let ast::ItemFn(_, _, _, abi, ref generics, _) = i.node {
if abi != abi::Rust && !generics.is_type_parameterized() {
rbml_w.wr_tagged_u32(tag_reachable_extern_fn_id, *id);
}
block: &'v ast::Block, span: Span, _: ast::NodeId) {
let (is_item_fn, is_unsafe_fn) = match fn_kind {
- visit::FkItemFn(_, _, fn_style, _, _) =>
- (true, fn_style == ast::Unsafety::Unsafe),
+ visit::FkItemFn(_, _, unsafety, _, _) =>
+ (true, unsafety == ast::Unsafety::Unsafe),
visit::FkMethod(_, sig, _) =>
(true, sig.unsafety == ast::Unsafety::Unsafe),
_ => (false, false),
fn give_expl_lifetime_param(&self,
decl: &ast::FnDecl,
unsafety: ast::Unsafety,
+ constness: ast::Constness,
ident: ast::Ident,
opt_explicit_self: Option<&ast::ExplicitSelf_>,
generics: &ast::Generics,
Some(ref node) => match *node {
ast_map::NodeItem(ref item) => {
match item.node {
- ast::ItemFn(ref fn_decl, pur, _, ref gen, _) => {
- Some((fn_decl, gen, pur, item.ident, None, item.span))
+ ast::ItemFn(ref fn_decl, unsafety, constness, _, ref gen, _) => {
+ Some((fn_decl, gen, unsafety, constness,
+ item.ident, None, item.span))
},
_ => None
}
Some((&sig.decl,
&sig.generics,
sig.unsafety,
+ sig.constness,
item.ident,
Some(&sig.explicit_self.node),
item.span))
Some((&sig.decl,
&sig.generics,
sig.unsafety,
+ sig.constness,
item.ident,
Some(&sig.explicit_self.node),
item.span))
},
None => None
};
- let (fn_decl, generics, unsafety, ident, expl_self, span)
+ let (fn_decl, generics, unsafety, constness, ident, expl_self, span)
= node_inner.expect("expect item fn");
let rebuilder = Rebuilder::new(self.tcx, fn_decl, expl_self,
generics, same_regions, &life_giver);
let (fn_decl, expl_self, generics) = rebuilder.rebuild();
- self.give_expl_lifetime_param(&fn_decl, unsafety, ident,
+ self.give_expl_lifetime_param(&fn_decl, unsafety, constness, ident,
expl_self.as_ref(), &generics, span);
}
}
fn give_expl_lifetime_param(&self,
decl: &ast::FnDecl,
unsafety: ast::Unsafety,
+ constness: ast::Constness,
ident: ast::Ident,
opt_explicit_self: Option<&ast::ExplicitSelf_>,
generics: &ast::Generics,
span: codemap::Span) {
- let suggested_fn = pprust::fun_to_string(decl, unsafety, ident,
- opt_explicit_self, generics);
+ let suggested_fn = pprust::fun_to_string(decl, unsafety, constness, ident,
+ opt_explicit_self, generics);
let msg = format!("consider using an explicit lifetime \
parameter as shown: {}", suggested_fn);
self.tcx.sess.span_help(span, &msg[..]);
let method_id_opt = match tcx.map.find(parent) {
Some(node) => match node {
ast_map::NodeItem(item) => match item.node {
- ast::ItemFn(_, _, _, ref gen, _) => {
+ ast::ItemFn(_, _, _, _, ref gen, _) => {
taken.push_all(&gen.lifetimes);
None
},
match item.node {
ast::ItemImpl(_, _, ref generics, _, _, _) |
- ast::ItemFn(_, _, _, ref generics, _) => {
+ ast::ItemFn(_, _, _, _, ref generics, _) => {
generics_require_inlining(generics)
}
_ => false,
// but all other rust-only interfaces can be private (they will not
// participate in linkage after this product is produced)
if let ast_map::NodeItem(item) = *node {
- if let ast::ItemFn(_, _, abi, _, _) = item.node {
+ if let ast::ItemFn(_, _, _, abi, _, _) = item.node {
if abi != abi::Rust {
self.reachable_symbols.insert(search_item);
}
match *node {
ast_map::NodeItem(item) => {
match item.node {
- ast::ItemFn(_, _, _, _, ref search_block) => {
+ ast::ItemFn(_, _, _, _, _, ref search_block) => {
if item_might_be_inlined(&*item) {
visit::walk_block(self, &**search_block)
}
fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, _: ast::NodeId) {
match fk {
- visit::FkItemFn(_, generics, _, _, _) => {
+ visit::FkItemFn(_, generics, _, _, _, _) => {
self.visit_early_late(subst::FnSpace, generics, |this| {
this.walk_fn(fk, fd, b, s)
})
use syntax::ast;
use syntax::ast::{Attribute, Block, Crate, DefId, FnDecl, NodeId, Variant};
use syntax::ast::{Item, Generics, StructField};
-use syntax::ast_util::is_local;
+use syntax::ast_util::{is_local, PostExpansionMethod};
use syntax::attr::{Stability, AttrMetaMethods};
use syntax::visit::{FnKind, Visitor};
use syntax::feature_gate::emit_feature_err;
}
Some(ast_map::NodeItem(item)) => {
match item.node {
- ast::ItemFn(_, _, _, _, ref body) => {
+ ast::ItemFn(_, _, _, _, _, ref body) => {
// We assume this is a function.
let fn_def_id = ast_util::local_def(id);
let fn_scheme = lookup_item_type(cx, fn_def_id);
},
_ => (),
},
- visit::FkItemFn(ident, _, _, _, _) => {
+ visit::FkItemFn(ident, _, _, _, _, _) => {
self.check_snake_case(cx, "function", &token::get_ident(ident), Some(span))
},
_ => (),
ast::NodeId, ast::NodeId, ast::Ident, ast::NodeId) -> bool;
let (name, checker) = match fn_kind {
- visit::FkItemFn(name, _, _, _, _) => (name, id_refers_to_this_fn as F),
+ visit::FkItemFn(name, _, _, _, _, _) => (name, id_refers_to_this_fn as F),
visit::FkMethod(name, _, _) => (name, id_refers_to_this_method as F),
// closures can't recur, so they don't matter.
visit::FkFnBlock => return
.define_value(DefConst(local_def(item.id)), sp, modifiers);
parent.clone()
}
- ItemFn(_, _, _, _, _) => {
+ ItemFn(_, _, _, _, _, _) => {
let name_bindings = self.add_child(name, parent, ForbidDuplicateValues, sp);
let def = DefFn(local_def(item.id), false);
ItemRibKind),
|this| visit::walk_item(this, item));
}
- ItemFn(_, _, _, ref generics, _) => {
+ ItemFn(_, _, _, _, ref generics, _) => {
self.with_type_parameter_rib(HasTypeParameters(generics,
FnSpace,
ItemRibKind),
let blk = match tcx.map.find(id) {
Some(ast_map::NodeItem(i)) => {
match i.node {
- ast::ItemFn(_, _, _, _, ref blk) => {
+ ast::ItemFn(_, _, _, _, _, ref blk) => {
blk
}
_ => tcx.sess.bug("unexpected item variant in has_nested_returns")
let from_external = ccx.external_srcs().borrow().contains_key(&item.id);
match item.node {
- ast::ItemFn(ref decl, _fn_style, abi, ref generics, ref body) => {
+ ast::ItemFn(ref decl, _, _, abi, ref generics, ref body) => {
if !generics.is_type_parameterized() {
let trans_everywhere = attr::requests_inline(&item.attrs);
// Ignore `trans_everywhere` for cross-crate inlined items
}
}
- ast::ItemFn(_, _, abi, _, _) => {
+ ast::ItemFn(_, _, _, abi, _, _) => {
let sym = sym();
let llfn = if abi == Rust {
register_fn(ccx, i.span, sym, i.id, ty)
trans_item(ccx, &**item);
let linkage = match item.node {
- ast::ItemFn(_, _, _, ref generics, _) => {
+ ast::ItemFn(_, _, _, _, ref generics, _) => {
if generics.is_type_parameterized() {
// Generics have no symbol, so they can't be given any
// linkage.
ast_map::NodeItem(i) => {
match *i {
ast::Item {
- node: ast::ItemFn(ref decl, _, abi, _, ref body),
+ node: ast::ItemFn(ref decl, _, _, abi, _, ref body),
..
} => {
let d = mk_lldecl(abi);
&enum_definition.variants,
it.id);
}
- ast::ItemFn(_, _, _, _, _) => {} // entirely within check_item_body
+ ast::ItemFn(..) => {} // entirely within check_item_body
ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
match ty::impl_trait_ref(ccx.tcx, local_def(it.id)) {
ty::item_path_str(ccx.tcx, local_def(it.id)));
let _indenter = indenter();
match it.node {
- ast::ItemFn(ref decl, _, _, _, ref body) => {
+ ast::ItemFn(ref decl, _, _, _, _, ref body) => {
let fn_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
check_bare_fn(ccx, &**decl, &**body, it.id, it.span, fn_pty.ty, param_env);
let ty = ccx.icx(&()).to_ty(&ExplicitRscope, &**t);
ty::TypeScheme { ty: ty, generics: ty::Generics::empty() }
}
- ast::ItemFn(ref decl, unsafety, abi, ref generics, _) => {
+ ast::ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
let ty_generics = ty_generics_for_fn(ccx, generics, &ty::Generics::empty());
let tofd = astconv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &**decl);
let ty = ty::mk_bare_fn(tcx, Some(local_def(it.id)), tcx.mk_bare_fn(tofd));
ast::ItemStatic(..) | ast::ItemConst(..) => {
ty::GenericPredicates::empty()
}
- ast::ItemFn(_, _, _, ref ast_generics, _) => {
+ ast::ItemFn(_, _, _, _, ref ast_generics, _) => {
ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
}
ast::ItemTy(_, ref generics) => {
match tcx.map.find(main_id) {
Some(ast_map::NodeItem(it)) => {
match it.node {
- ast::ItemFn(_, _, _, ref ps, _)
+ ast::ItemFn(_, _, _, _, ref ps, _)
if ps.is_parameterized() => {
span_err!(ccx.tcx.sess, main_span, E0131,
"main function is not allowed to have type parameters");
match tcx.map.find(start_id) {
Some(ast_map::NodeItem(it)) => {
match it.node {
- ast::ItemFn(_,_,_,ref ps,_)
+ ast::ItemFn(_,_,_,_,ref ps,_)
if ps.is_parameterized() => {
span_err!(tcx.sess, start_span, E0132,
"start function is not allowed to have type parameters");
decl: decl,
generics: (&t.generics, &predicates, subst::FnSpace).clean(cx),
unsafety: style,
+ constness: ast::Constness::NotConst,
abi: abi,
}
}
}) => {
clean::MethodItem(clean::Method {
unsafety: unsafety,
+ constness: ast::Constness::NotConst,
decl: decl,
self_: self_,
generics: generics,
pub generics: Generics,
pub self_: SelfTy,
pub unsafety: ast::Unsafety,
+ pub constness: ast::Constness,
pub decl: FnDecl,
pub abi: abi::Abi
}
Method {
generics: self.generics.clean(cx),
self_: self.explicit_self.node.clean(cx),
- unsafety: self.unsafety.clone(),
+ unsafety: self.unsafety,
+ constness: self.constness,
decl: decl,
abi: self.abi
}
pub decl: FnDecl,
pub generics: Generics,
pub unsafety: ast::Unsafety,
- pub abi: abi::Abi
+ pub constness: ast::Constness,
+ pub abi: abi::Abi,
}
impl Clean<Item> for doctree::Function {
decl: self.decl.clean(cx),
generics: self.generics.clean(cx),
unsafety: self.unsafety,
+ constness: self.constness,
abi: self.abi,
}),
}
generics: generics.clean(cx),
unsafety: ast::Unsafety::Unsafe,
abi: abi::Rust,
+ constness: ast::Constness::NotConst,
})
}
ast::ForeignItemStatic(ref ty, mutbl) => {
pub vis: ast::Visibility,
pub stab: Option<attr::Stability>,
pub unsafety: ast::Unsafety,
+ pub constness: ast::Constness,
pub whence: Span,
pub generics: ast::Generics,
pub abi: abi::Abi,
/// space after it.
#[derive(Copy, Clone)]
pub struct UnsafetySpace(pub ast::Unsafety);
+/// Similarly to VisSpace, this structure is used to render a function constness
+/// with a space after it.
+#[derive(Copy)]
+pub struct ConstnessSpace(pub ast::Constness);
/// Wrapper struct for properly emitting a method declaration.
pub struct Method<'a>(pub &'a clean::SelfTy, pub &'a clean::FnDecl);
/// Similar to VisSpace, but used for mutability
}
}
+impl ConstnessSpace {
+ pub fn get(&self) -> ast::Constness {
+ let ConstnessSpace(v) = *self; v
+ }
+}
+
impl<'a, T: fmt::Display> fmt::Display for CommaSep<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for (i, item) in self.0.iter().enumerate() {
}
}
+impl fmt::Display for ConstnessSpace {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self.get() {
+ ast::Constness::Const => write!(f, "const "),
+ ast::Constness::NotConst => Ok(())
+ }
+ }
+}
+
impl fmt::Display for clean::Import {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
use doctree;
use fold::DocFolder;
use html::escape::Escape;
+use html::format::{ConstnessSpace};
use html::format::{TyParamBounds, WhereClause, href, AbiSpace};
use html::format::{VisSpace, Method, UnsafetySpace, MutableSpace};
use html::highlight;
fn item_function(w: &mut fmt::Formatter, it: &clean::Item,
f: &clean::Function) -> fmt::Result {
- try!(write!(w, "<pre class='rust fn'>{vis}{unsafety}{abi}fn \
+ try!(write!(w, "<pre class='rust fn'>{vis}{unsafety}{abi}{constness}fn \
{name}{generics}{decl}{where_clause}</pre>",
vis = VisSpace(it.visibility),
unsafety = UnsafetySpace(f.unsafety),
abi = AbiSpace(f.abi),
+ constness = ConstnessSpace(f.constness),
name = it.name.as_ref().unwrap(),
generics = f.generics,
where_clause = WhereClause(&f.generics),
fn render_assoc_item(w: &mut fmt::Formatter, meth: &clean::Item,
link: AssocItemLink) -> fmt::Result {
- fn method(w: &mut fmt::Formatter, it: &clean::Item,
- unsafety: ast::Unsafety, abi: abi::Abi,
- g: &clean::Generics, selfty: &clean::SelfTy,
- d: &clean::FnDecl, link: AssocItemLink) -> fmt::Result {
+ fn method(w: &mut fmt::Formatter,
+ it: &clean::Item,
+ unsafety: ast::Unsafety,
+ constness: ast::Constness,
+ abi: abi::Abi,
+ g: &clean::Generics,
+ selfty: &clean::SelfTy,
+ d: &clean::FnDecl,
+ link: AssocItemLink)
+ -> fmt::Result {
use syntax::abi::Abi;
let name = it.name.as_ref().unwrap();
href(did).map(|p| format!("{}{}", p.0, anchor)).unwrap_or(anchor)
}
};
- write!(w, "{}{}fn <a href='{href}' class='fnname'>{name}</a>\
+ write!(w, "{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
{generics}{decl}{where_clause}",
- match unsafety {
- ast::Unsafety::Unsafe => "unsafe ",
- _ => "",
- },
+ UnsafetySpace(unsafety),
+ ConstnessSpace(constness),
match abi {
Abi::Rust => String::new(),
a => format!("extern {} ", a.to_string())
}
match meth.inner {
clean::TyMethodItem(ref m) => {
- method(w, meth, m.unsafety, m.abi, &m.generics, &m.self_, &m.decl,
- link)
+ method(w, meth, m.unsafety, ast::Constness::NotConst,
+ m.abi, &m.generics, &m.self_, &m.decl, link)
}
clean::MethodItem(ref m) => {
- method(w, meth, m.unsafety, m.abi, &m.generics, &m.self_, &m.decl,
+ method(w, meth, m.unsafety, m.constness,
+ m.abi, &m.generics, &m.self_, &m.decl,
link)
}
clean::AssociatedConstItem(ref ty, ref default) => {
pub fn visit_fn(&mut self, item: &ast::Item,
name: ast::Ident, fd: &ast::FnDecl,
- unsafety: &ast::Unsafety, abi: &abi::Abi,
+ unsafety: &ast::Unsafety,
+ constness: ast::Constness,
+ _abi: &abi::Abi,
gen: &ast::Generics) -> Function {
debug!("Visiting fn");
Function {
whence: item.span,
generics: gen.clone(),
unsafety: *unsafety,
+ constness: constness,
abi: *abi,
}
}
om.enums.push(self.visit_enum_def(item, name, ed, gen)),
ast::ItemStruct(ref sd, ref gen) =>
om.structs.push(self.visit_struct_def(item, name, &**sd, gen)),
- ast::ItemFn(ref fd, ref pur, ref abi, ref gen, _) =>
- om.fns.push(self.visit_fn(item, name, &**fd, pur, abi, gen)),
+ ast::ItemFn(ref fd, unsafety, constness, ref abi, ref gen, _) =>
+ om.fns.push(self.visit_fn(item, name, &**fd, unsafety,
+ constness, abi, gen)),
ast::ItemTy(ref ty, ref gen) => {
let t = Typedef {
ty: ty.clone(),
Normal,
}
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum Constness {
+ Const,
+ NotConst,
+}
+
impl fmt::Display for Unsafety {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(match *self {
pub type ExplicitSelf = Spanned<ExplicitSelf_>;
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+ Constness,
pub struct Mod {
/// A span from the first token past `{` to the last token until `}`.
/// For `mod foo;`, the inner span ranges from the first token
/// A `const` item
ItemConst(P<Ty>, P<Expr>),
/// A function declaration
- ItemFn(P<FnDecl>, Unsafety, Abi, Generics, P<Block>),
+ ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, P<Block>),
/// A module
ItemMod(Mod),
/// An external module
ident: ast::Ident,
decl: &'a ast::FnDecl,
unsafety: ast::Unsafety,
+ constness: ast::Constness,
abi: abi::Abi,
vis: ast::Visibility,
generics: &'a ast::Generics,
pub fn kind(self) -> visit::FnKind<'a> {
let item = |p: ItemFnParts<'a>| -> visit::FnKind<'a> {
- visit::FkItemFn(p.ident, p.generics, p.unsafety, p.abi, p.vis)
+ visit::FkItemFn(p.ident, p.generics, p.unsafety, p.abi, p.constness, p.vis)
};
let closure = |_: ClosureParts| {
visit::FkFnBlock
{
match self.node {
ast_map::NodeItem(i) => match i.node {
- ast::ItemFn(ref decl, unsafety, abi, ref generics, ref block) =>
- item_fn(ItemFnParts{
- ident: i.ident, decl: &**decl, unsafety: unsafety, body: &**block,
- generics: generics, abi: abi, vis: i.vis, id: i.id, span: i.span
+ ast::ItemFn(ref decl, unsafety, constness, ref abi, ref generics, ref block) =>
+ item_fn(ItemFnParts {
+ id: i.id,
+ ident: i.ident,
+ decl: &**decl,
+ unsafety: unsafety,
+ constness: constness,
+ body: &**block,
+ generics: generics,
+ abi: abi,
+ vis: i.vis,
+ constness: constness,
+ span: i.span
}),
_ => panic!("item FnLikeNode that is not fn-like"),
},
token::gensym_ident(&pretty[..])
}
+ _,
pub fn struct_field_visibility(field: ast::StructField) -> Visibility {
match field.node.kind {
ast::NamedField(_, v) | ast::UnnamedField(v) => v
Vec::new(),
ast::ItemFn(self.fn_decl(inputs, output),
ast::Unsafety::Normal,
+ ast::Constness::NotConst,
abi::Rust,
generics,
body))
abi: abi,
explicit_self: explicit_self,
unsafety: unsafety,
+ constness: ast::Constness::NotConst,
decl: fn_decl
}, body_block)
})
/// Expand item_underscore
fn expand_item_underscore(item: ast::Item_, fld: &mut MacroExpander) -> ast::Item_ {
match item {
- ast::ItemFn(decl, fn_style, abi, generics, body) => {
+ ast::ItemFn(decl, unsafety, constness, abi, generics, body) => {
let (rewritten_fn_decl, rewritten_body)
= expand_and_rename_fn_decl_and_block(decl, body, fld);
let expanded_generics = fold::noop_fold_generics(generics,fld);
- ast::ItemFn(rewritten_fn_decl, fn_style, abi, expanded_generics, rewritten_body)
+ ast::ItemFn(rewritten_fn_decl, unsafety, constness, abi,
+ expanded_generics, rewritten_body)
}
_ => noop_fold_item_underscore(item, fld)
}
span: Span,
_node_id: NodeId) {
match fn_kind {
- visit::FkItemFn(_, _, _, abi, _) if abi == Abi::RustIntrinsic => {
+ visit::FkItemFn(_, _, _, _, abi, _) if abi == Abi::RustIntrinsic => {
self.gate_feature("intrinsics",
span,
"intrinsics are subject to change")
}
- visit::FkItemFn(_, _, _, abi, _) |
+ visit::FkItemFn(_, _, _, _, abi, _) |
visit::FkMethod(_, &ast::MethodSig { abi, .. }, _) if abi == Abi::RustCall => {
self.gate_feature("unboxed_closures",
span,
ItemConst(t, e) => {
ItemConst(folder.fold_ty(t), folder.fold_expr(e))
}
- ItemFn(decl, unsafety, abi, generics, body) => {
+ ItemFn(decl, unsafety, constness, abi, generics, body) => {
ItemFn(
folder.fold_fn_decl(decl),
unsafety,
+ constness,
abi,
folder.fold_generics(generics),
folder.fold_block(body)
unsafety: sig.unsafety,
decl: folder.fold_fn_decl(sig.decl)
}
+ constness,
+ constness,
}
pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue};
use ast::{BiBitAnd, BiBitOr, BiBitXor, BiRem, BiLt, BiGt, Block};
use ast::{BlockCheckMode, CaptureByRef, CaptureByValue, CaptureClause};
-use ast::{ConstImplItem, ConstTraitItem, Crate, CrateConfig};
+use ast::{Constness, ConstImplItem, ConstTraitItem, Crate, CrateConfig};
use ast::{Decl, DeclItem, DeclLocal, DefaultBlock, DefaultReturn};
use ast::{UnDeref, BiDiv, EMPTY_CTXT, EnumDef, ExplicitSelf};
use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
};
(ident, ConstTraitItem(ty, default))
} else {
- let style = try!(p.parse_unsafety());
+ let unsafety = try!(p.parse_unsafety());
let abi = if try!(p.eat_keyword(keywords::Extern)) {
try!(p.parse_opt_abi()).unwrap_or(abi::C)
} else {
generics.where_clause = try!(p.parse_where_clause());
let sig = ast::MethodSig {
- unsafety: style,
+ unsafety: unsafety,
+ constness: ast::Constness::NotConst;
decl: d,
generics: generics,
abi: abi,
}
/// Parse an item-position function declaration.
- fn parse_item_fn(&mut self, unsafety: Unsafety, abi: abi::Abi) -> PResult<ItemInfo> {
+ fn parse_item_fn(&mut self,
+ unsafety: Unsafety,
+ constness: Constness,
+ abi: abi::Abi)
+ -> PResult<ItemInfo> {
let (ident, mut generics) = try!(self.parse_fn_header());
let decl = try!(self.parse_fn_decl(false));
generics.where_clause = try!(self.parse_where_clause());
let (inner_attrs, body) = try!(self.parse_inner_attrs_and_block());
- Ok((ident, ItemFn(decl, unsafety, abi, generics, body), Some(inner_attrs)))
+ Ok((ident, ItemFn(decl, unsafety, constness, abi, generics, body), Some(inner_attrs)))
}
/// Parse an impl item.
}
Ok((token::special_idents::invalid, vec![], ast::MacImplItem(m)))
} else {
- let unsafety = try!(self.parse_unsafety());
- let abi = if try!(self.eat_keyword(keywords::Extern)) {
- try!(self.parse_opt_abi()).unwrap_or(abi::C)
+ let is_const_fn = !is_trait_impl && self.eat_keyword(keywords::Const);
+ let (constness, unsafety, abi) = if is_const_fn {
+ (Constness::Const, Unsafety::Normal, abi::Rust)
} else {
- abi::Rust
+ let unsafety = try!(self.parse_unsafety());
+ let abi = if try!(self.eat_keyword(keywords::Extern)) {
+ try!(self.parse_opt_abi()).unwrap_or(abi::C)
+ } else {
+ abi::Rust
+ };
+ (Constness::NotConst, unsafety, abi)
};
try!(self.expect_keyword(keywords::Fn));
let ident = try!(self.parse_ident());
abi: abi,
explicit_self: explicit_self,
unsafety: unsafety,
+ constness: constness;
decl: decl
}, body)))
}
// EXTERN FUNCTION ITEM
let abi = opt_abi.unwrap_or(abi::C);
let (ident, item_, extra_attrs) =
- try!(self.parse_item_fn(Unsafety::Normal, abi));
+ try!(self.parse_item_fn(Unsafety::Normal, Constness::NotConst, abi));
let last_span = self.last_span;
let item = self.mk_item(lo,
last_span.hi,
return Ok(Some(item));
}
if try!(self.eat_keyword(keywords::Const) ){
+ if self.check_keyword(keywords::Fn) {
+ // CONST FUNCTION ITEM
+ self.bump();
+ let (ident, item_, extra_attrs) =
+ self.parse_item_fn(Unsafety::Normal, Constness::Const, abi::Rust);
+ let last_span = self.last_span;
+ let item = self.mk_item(lo,
+ last_span.hi,
+ ident,
+ item_,
+ visibility,
+ maybe_append(attrs, extra_attrs));
+ return Ok(item);
+ }
+
// CONST ITEM
if try!(self.eat_keyword(keywords::Mut) ){
let last_span = self.last_span;
// FUNCTION ITEM
try!(self.bump());
let (ident, item_, extra_attrs) =
- try!(self.parse_item_fn(Unsafety::Normal, abi::Rust));
+ try!(self.parse_item_fn(Unsafety::Normal, Constness::NotConst, abi::Rust));
let last_span = self.last_span;
let item = self.mk_item(lo,
last_span.hi,
};
try!(self.expect_keyword(keywords::Fn));
let (ident, item_, extra_attrs) =
- try!(self.parse_item_fn(Unsafety::Unsafe, abi));
+ try!(self.parse_item_fn(Unsafety::Unsafe, Constness::NotConst, abi));
let last_span = self.last_span;
let item = self.mk_item(lo,
last_span.hi,
to_string(|s| s.print_ident(*id))
}
+<<<<<<< HEAD
pub fn fun_to_string(decl: &ast::FnDecl, unsafety: ast::Unsafety, name: ast::Ident,
opt_explicit_self: Option<&ast::ExplicitSelf_>,
generics: &ast::Generics) -> String {
to_string(|s| {
+||||||| parent of 61a958e... syntax: parse `const fn` for free functions and inherent methods.
+pub fn fun_to_string(decl: &ast::FnDecl, unsafety: ast::Unsafety, name: ast::Ident,
+ opt_explicit_self: Option<&ast::ExplicitSelf_>,
+ generics: &ast::Generics) -> String {
+ $to_string(|s| {
+=======
+pub fn fun_to_string(decl: &ast::FnDecl,
+ unsafety: ast::Unsafety,
+ constness: ast::Constness,
+ name: ast::Ident,
+ opt_explicit_self: Option<&ast::ExplicitSelf_>,
+ generics: &ast::Generics)
+ -> String {
+ $to_string(|s| {
+>>>>>>> 61a958e... syntax: parse `const fn` for free functions and inherent methods.
try!(s.head(""));
- try!(s.print_fn(decl, unsafety, abi::Rust, Some(name),
+ try!(s.print_fn(decl, unsafety, constness, abi::Rust, Some(name),
generics, opt_explicit_self, ast::Inherited));
try!(s.end()); // Close the head box
s.end() // Close the outer box
match item.node {
ast::ForeignItemFn(ref decl, ref generics) => {
try!(self.head(""));
- try!(self.print_fn(&**decl, ast::Unsafety::Normal,
+ try!(self.print_fn(decl, ast::Unsafety::Normal,
+ ast::Constness::NotConst,
abi::Rust, Some(item.ident),
generics, None, item.vis));
try!(self.end()); // end head-ibox
try!(word(&mut self.s, ";"));
try!(self.end()); // end the outer cbox
}
- ast::ItemFn(ref decl, unsafety, abi, ref typarams, ref body) => {
+ ast::ItemFn(ref decl, unsafety, constness, abi, ref typarams, ref body) => {
try!(self.head(""));
try!(self.print_fn(
decl,
unsafety,
+ constness,
abi,
Some(item.ident),
typarams,
-> io::Result<()> {
self.print_fn(&m.decl,
m.unsafety,
+ m.constness,
m.abi,
Some(ident),
&m.generics,
pub fn print_fn(&mut self,
decl: &ast::FnDecl,
unsafety: ast::Unsafety,
+ constness: ast::Constness,
abi: abi::Abi,
name: Option<ast::Ident>,
generics: &ast::Generics,
opt_explicit_self: Option<&ast::ExplicitSelf_>,
vis: ast::Visibility) -> io::Result<()> {
- try!(self.print_fn_header_info(unsafety, abi, vis));
+ try!(self.print_fn_header_info(unsafety, constness, abi, vis));
if let Some(name) = name {
try!(self.nbsp());
predicates: Vec::new(),
},
};
- try!(self.print_fn(decl, unsafety, abi, name,
- &generics, opt_explicit_self,
+ try!(self.print_fn(decl,
+ unsafety,
+ ast::Constness::NotConst,
+ abi,
+ name,
+ generics,
+ opt_explicit_self,
ast::Inherited));
self.end()
}
pub fn print_fn_header_info(&mut self,
unsafety: ast::Unsafety,
+ constness: ast::Constness,
abi: abi::Abi,
vis: ast::Visibility) -> io::Result<()> {
try!(word(&mut self.s, &visibility_qualified(vis, "")));
try!(self.print_unsafety(unsafety));
+ match constness {
+ ast::Constness::NotConst => {}
+ ast::Constness::Const => try!(self.word_nbsp("unsafe"))
+ }
+
if abi != abi::Rust {
try!(self.word_nbsp("extern"));
try!(self.word_nbsp(&abi.to_string()));
variadic: false
};
let generics = ast_util::empty_generics();
- assert_eq!(fun_to_string(&decl, ast::Unsafety::Normal, abba_ident,
- None, &generics),
+ assert_eq!(fun_to_string(&decl, ast::Unsafety::Normal,
+ ast::Constness::NotConst,
+ abba_ident,
+ None, &generics),
"fn abba()");
}
let i = if is_test_fn(&self.cx, &*i) || is_bench_fn(&self.cx, &*i) {
match i.node {
- ast::ItemFn(_, ast::Unsafety::Unsafe, _, _, _) => {
+ ast::ItemFn(_, ast::Unsafety::Unsafe, _, _, _, _) => {
let diag = self.cx.span_diagnostic;
panic!(diag.span_fatal(i.span, "unsafe functions cannot be used for tests"));
}
fn has_test_signature(i: &ast::Item) -> HasTestSignature {
match &i.node {
- &ast::ItemFn(ref decl, _, _, ref generics, _) => {
+ &ast::ItemFn(ref decl, _, _, _, ref generics, _) => {
let no_output = match decl.output {
ast::DefaultReturn(..) => true,
ast::Return(ref t) if t.node == ast::TyTup(vec![]) => true,
fn has_test_signature(i: &ast::Item) -> bool {
match i.node {
- ast::ItemFn(ref decl, _, _, ref generics, _) => {
+ ast::ItemFn(ref decl, _, _, _, ref generics, _) => {
let input_cnt = decl.inputs.len();
let no_output = match decl.output {
ast::DefaultReturn(..) => true,
let main_ret_ty = ecx.ty(sp, ast::TyTup(vec![]));
let main_body = ecx.block_all(sp, vec![call_test_main], None);
let main = ast::ItemFn(ecx.fn_decl(vec![], main_ret_ty),
- ast::Unsafety::Normal, ::abi::Rust, empty_generics(), main_body);
+ ast::Unsafety::Normal,
+ ast::Constness::NotConst,
+ ::abi::Rust, empty_generics(), main_body);
let main = P(ast::Item {
ident: token::str_to_ident("main"),
attrs: vec![main_attr],
#[derive(Copy, Clone)]
pub enum FnKind<'a> {
/// fn foo() or extern "Abi" fn foo()
- FkItemFn(Ident, &'a Generics, Unsafety, Abi, Visibility),
+ FkItemFn(Ident, &'a Generics, Unsafety, Constness, Abi, Visibility),
/// fn foo(&self)
FkMethod(Ident, &'a MethodSig, Option<Visibility>),
visitor.visit_ty(&**typ);
visitor.visit_expr(&**expr);
}
- ItemFn(ref declaration, fn_style, abi, ref generics, ref body) => {
- visitor.visit_fn(FkItemFn(item.ident, generics, fn_style, abi, item.vis),
+ ItemFn(ref declaration, unsafety, constness, abi, ref generics, ref body) => {
+ visitor.visit_fn(FkItemFn(item.ident, generics, unsafety,
+ constness, abi, item.vis),
&**declaration,
&**body,
item.span,