Skip to content

Commit

Permalink
rustc: const-qualify const fn function and method calls.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb authored and nikomatsakis committed May 21, 2015
1 parent af37957 commit 1bd4205
Show file tree
Hide file tree
Showing 8 changed files with 288 additions and 57 deletions.
2 changes: 2 additions & 0 deletions src/librustc/metadata/common.rs
Expand Up @@ -262,3 +262,5 @@ pub const tag_item_super_predicates: usize = 0xa3;
pub const tag_defaulted_trait: usize = 0xa4;

pub const tag_impl_coerce_unsized_kind: usize = 0xa5;

pub const tag_items_data_item_constness: usize = 0xa6;
5 changes: 5 additions & 0 deletions src/librustc/metadata/csearch.rs
Expand Up @@ -384,6 +384,11 @@ pub fn is_typedef(cstore: &cstore::CStore, did: ast::DefId) -> bool {
decoder::is_typedef(&*cdata, did.node)
}

pub fn is_const_fn(cstore: &cstore::CStore, did: ast::DefId) -> bool {
let cdata = cstore.get_crate_data(did.krate);
decoder::is_const_fn(&*cdata, did.node)
}

pub fn get_stability(cstore: &cstore::CStore,
def: ast::DefId)
-> Option<attr::Stability> {
Expand Down
21 changes: 21 additions & 0 deletions src/librustc/metadata/decoder.rs
Expand Up @@ -178,6 +178,19 @@ fn item_visibility(item: rbml::Doc) -> ast::Visibility {
}
}

fn fn_constness(item: rbml::Doc) -> ast::Constness {
match reader::maybe_get_doc(item, tag_items_data_item_constness) {
None => ast::Constness::NotConst,
Some(constness_doc) => {
match reader::doc_as_u8(constness_doc) as char {
'c' => ast::Constness::Const,
'n' => ast::Constness::NotConst,
_ => panic!("unknown constness character")
}
}
}
}

fn item_sort(item: rbml::Doc) -> Option<char> {
let mut ret = None;
reader::tagged_docs(item, tag_item_trait_item_sort, |doc| {
Expand Down Expand Up @@ -1525,6 +1538,14 @@ pub fn is_typedef(cdata: Cmd, id: ast::NodeId) -> bool {
}
}

pub fn is_const_fn(cdata: Cmd, id: ast::NodeId) -> bool {
let item_doc = lookup_item(id, cdata.data());
match fn_constness(item_doc) {
ast::Constness::Const => true,
ast::Constness::NotConst => false,
}
}

fn doc_generics<'tcx>(base_doc: rbml::Doc,
tcx: &ty::ctxt<'tcx>,
cdata: Cmd,
Expand Down
22 changes: 19 additions & 3 deletions src/librustc/metadata/encoder.rs
Expand Up @@ -581,6 +581,16 @@ fn encode_visibility(rbml_w: &mut Encoder, visibility: ast::Visibility) {
rbml_w.wr_tagged_u8(tag_items_data_item_visibility, ch as u8);
}

fn encode_constness(rbml_w: &mut Encoder, constness: ast::Constness) {
rbml_w.start_tag(tag_items_data_item_constness);
let ch = match constness {
ast::Constness::Const => 'c',
ast::Constness::NotConst => 'n',
};
rbml_w.wr_str(&ch.to_string());
rbml_w.end_tag();
}

fn encode_explicit_self(rbml_w: &mut Encoder,
explicit_self: &ty::ExplicitSelfCategory) {
let tag = tag_item_trait_method_explicit_self;
Expand Down Expand Up @@ -867,10 +877,14 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
encode_attributes(rbml_w, &impl_item.attrs);
let scheme = ty::lookup_item_type(ecx.tcx, m.def_id);
let any_types = !scheme.generics.types.is_empty();
if any_types || is_default_impl || attr::requests_inline(&impl_item.attrs) {
let needs_inline = any_types || is_default_impl ||
attr::requests_inline(&impl_item.attrs);
let constness = ast_method.pe_constness();
if needs_inline || constness == ast::Constness::Const {
encode_inlined_item(ecx, rbml_w, IIImplItemRef(local_def(parent_id),
impl_item));
}
encode_constness(rbml_w, constness);
if !any_types {
encode_symbol(ecx, rbml_w, m.def_id.node);
}
Expand Down Expand Up @@ -1049,7 +1063,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_stability(rbml_w, stab);
rbml_w.end_tag();
}
ast::ItemFn(ref decl, _, _, _, ref generics, _) => {
ast::ItemFn(ref decl, _, constness, _, ref generics, _) => {
add_to_index(item, rbml_w, index);
rbml_w.start_tag(tag_items_data_item);
encode_def_id(rbml_w, def_id);
Expand All @@ -1059,12 +1073,14 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_name(rbml_w, item.ident.name);
encode_path(rbml_w, path);
encode_attributes(rbml_w, &item.attrs);
if tps_len > 0 || attr::requests_inline(&item.attrs) {
let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs);
if needs_inline || constness == ast::Constness::Const {
encode_inlined_item(ecx, rbml_w, IIItemRef(item));
}
if tps_len == 0 {
encode_symbol(ecx, rbml_w, item.id);
}
encode_constness(rbml_w, constness);
encode_visibility(rbml_w, vis);
encode_stability(rbml_w, stab);
encode_method_argument_names(rbml_w, &**decl);
Expand Down

0 comments on commit 1bd4205

Please sign in to comment.