librustc: use unboxed closures
This commit is contained in:
parent
933e7b4a3e
commit
1195708f64
@ -464,9 +464,11 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
|
||||
/// Merge the lints specified by any lint attributes into the
|
||||
/// current lint context, call the provided function, then reset the
|
||||
/// lints in effect to their previous state.
|
||||
fn with_lint_attrs(&mut self,
|
||||
attrs: &[ast::Attribute],
|
||||
f: |&mut Context|) {
|
||||
fn with_lint_attrs<F>(&mut self,
|
||||
attrs: &[ast::Attribute],
|
||||
f: F) where
|
||||
F: FnOnce(&mut Context),
|
||||
{
|
||||
// Parse all of the lint attributes, and then add them all to the
|
||||
// current dictionary of lint information. Along the way, keep a history
|
||||
// of what we changed so we can roll everything back after invoking the
|
||||
@ -528,7 +530,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_ids(&mut self, f: |&mut ast_util::IdVisitor<Context>|) {
|
||||
fn visit_ids<F>(&mut self, f: F) where
|
||||
F: FnOnce(&mut ast_util::IdVisitor<Context>)
|
||||
{
|
||||
let mut v = ast_util::IdVisitor {
|
||||
operation: self,
|
||||
pass_through_items: false,
|
||||
|
@ -47,20 +47,22 @@ pub fn get_symbol(cstore: &cstore::CStore, def: ast::DefId) -> String {
|
||||
}
|
||||
|
||||
/// Iterates over all the language items in the given crate.
|
||||
pub fn each_lang_item(cstore: &cstore::CStore,
|
||||
cnum: ast::CrateNum,
|
||||
f: |ast::NodeId, uint| -> bool)
|
||||
-> bool {
|
||||
pub fn each_lang_item<F>(cstore: &cstore::CStore,
|
||||
cnum: ast::CrateNum,
|
||||
f: F)
|
||||
-> bool where
|
||||
F: FnMut(ast::NodeId, uint) -> bool,
|
||||
{
|
||||
let crate_data = cstore.get_crate_data(cnum);
|
||||
decoder::each_lang_item(&*crate_data, f)
|
||||
}
|
||||
|
||||
/// Iterates over each child of the given item.
|
||||
pub fn each_child_of_item(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId,
|
||||
callback: |decoder::DefLike,
|
||||
ast::Name,
|
||||
ast::Visibility|) {
|
||||
pub fn each_child_of_item<F>(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId,
|
||||
callback: F) where
|
||||
F: FnMut(decoder::DefLike, ast::Name, ast::Visibility),
|
||||
{
|
||||
let crate_data = cstore.get_crate_data(def_id.krate);
|
||||
let get_crate_data: decoder::GetCrateDataCb = |cnum| {
|
||||
cstore.get_crate_data(cnum)
|
||||
@ -73,11 +75,11 @@ pub fn each_child_of_item(cstore: &cstore::CStore,
|
||||
}
|
||||
|
||||
/// Iterates over each top-level crate item.
|
||||
pub fn each_top_level_item_of_crate(cstore: &cstore::CStore,
|
||||
cnum: ast::CrateNum,
|
||||
callback: |decoder::DefLike,
|
||||
ast::Name,
|
||||
ast::Visibility|) {
|
||||
pub fn each_top_level_item_of_crate<F>(cstore: &cstore::CStore,
|
||||
cnum: ast::CrateNum,
|
||||
callback: F) where
|
||||
F: FnMut(decoder::DefLike, ast::Name, ast::Visibility),
|
||||
{
|
||||
let crate_data = cstore.get_crate_data(cnum);
|
||||
let get_crate_data: decoder::GetCrateDataCb = |cnum| {
|
||||
cstore.get_crate_data(cnum)
|
||||
@ -195,9 +197,11 @@ pub fn get_methods_if_impl(cstore: &cstore::CStore,
|
||||
decoder::get_methods_if_impl(cstore.intr.clone(), &*cdata, def.node)
|
||||
}
|
||||
|
||||
pub fn get_item_attrs(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId,
|
||||
f: |Vec<ast::Attribute>|) {
|
||||
pub fn get_item_attrs<F>(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId,
|
||||
f: F) where
|
||||
F: FnOnce(Vec<ast::Attribute>),
|
||||
{
|
||||
let cdata = cstore.get_crate_data(def_id.krate);
|
||||
decoder::get_item_attrs(&*cdata, def_id.node, f)
|
||||
}
|
||||
@ -279,23 +283,29 @@ pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum)
|
||||
decoder::get_native_libraries(&*cdata)
|
||||
}
|
||||
|
||||
pub fn each_impl(cstore: &cstore::CStore,
|
||||
crate_num: ast::CrateNum,
|
||||
callback: |ast::DefId|) {
|
||||
pub fn each_impl<F>(cstore: &cstore::CStore,
|
||||
crate_num: ast::CrateNum,
|
||||
callback: F) where
|
||||
F: FnMut(ast::DefId),
|
||||
{
|
||||
let cdata = cstore.get_crate_data(crate_num);
|
||||
decoder::each_impl(&*cdata, callback)
|
||||
}
|
||||
|
||||
pub fn each_implementation_for_type(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId,
|
||||
callback: |ast::DefId|) {
|
||||
pub fn each_implementation_for_type<F>(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId,
|
||||
callback: F) where
|
||||
F: FnMut(ast::DefId),
|
||||
{
|
||||
let cdata = cstore.get_crate_data(def_id.krate);
|
||||
decoder::each_implementation_for_type(&*cdata, def_id.node, callback)
|
||||
}
|
||||
|
||||
pub fn each_implementation_for_trait(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId,
|
||||
callback: |ast::DefId|) {
|
||||
pub fn each_implementation_for_trait<F>(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId,
|
||||
callback: F) where
|
||||
F: FnMut(ast::DefId),
|
||||
{
|
||||
let cdata = cstore.get_crate_data(def_id.krate);
|
||||
decoder::each_implementation_for_trait(&*cdata, def_id.node, callback)
|
||||
}
|
||||
|
@ -113,16 +113,18 @@ impl CStore {
|
||||
self.metas.borrow_mut().insert(cnum, data);
|
||||
}
|
||||
|
||||
pub fn iter_crate_data(&self, i: |ast::CrateNum, &crate_metadata|) {
|
||||
pub fn iter_crate_data<I>(&self, mut i: I) where
|
||||
I: FnMut(ast::CrateNum, &crate_metadata),
|
||||
{
|
||||
for (&k, v) in self.metas.borrow().iter() {
|
||||
i(k, &**v);
|
||||
}
|
||||
}
|
||||
|
||||
/// Like `iter_crate_data`, but passes source paths (if available) as well.
|
||||
pub fn iter_crate_data_origins(&self, i: |ast::CrateNum,
|
||||
&crate_metadata,
|
||||
Option<CrateSource>|) {
|
||||
pub fn iter_crate_data_origins<I>(&self, mut i: I) where
|
||||
I: FnMut(ast::CrateNum, &crate_metadata, Option<CrateSource>),
|
||||
{
|
||||
for (&k, v) in self.metas.borrow().iter() {
|
||||
let origin = self.get_used_crate_source(k);
|
||||
origin.as_ref().map(|cs| { assert!(k == cs.cnum); });
|
||||
|
@ -60,8 +60,9 @@ pub type Cmd<'a> = &'a crate_metadata;
|
||||
// what crate that's in and give us a def_id that makes sense for the current
|
||||
// build.
|
||||
|
||||
fn lookup_hash<'a>(d: rbml::Doc<'a>, eq_fn: |&[u8]| -> bool,
|
||||
hash: u64) -> Option<rbml::Doc<'a>> {
|
||||
fn lookup_hash<'a, F>(d: rbml::Doc<'a>, mut eq_fn: F, hash: u64) -> Option<rbml::Doc<'a>> where
|
||||
F: FnMut(&[u8]) -> bool,
|
||||
{
|
||||
let index = reader::get_doc(d, tag_index);
|
||||
let table = reader::get_doc(index, tag_index_table);
|
||||
let hash_pos = table.start + (hash % 256 * 4) as uint;
|
||||
@ -448,7 +449,9 @@ pub enum DefLike {
|
||||
impl Copy for DefLike {}
|
||||
|
||||
/// Iterates over the language items in the given crate.
|
||||
pub fn each_lang_item(cdata: Cmd, f: |ast::NodeId, uint| -> bool) -> bool {
|
||||
pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where
|
||||
F: FnMut(ast::NodeId, uint) -> bool,
|
||||
{
|
||||
let root = rbml::Doc::new(cdata.data());
|
||||
let lang_items = reader::get_doc(root, tag_lang_items);
|
||||
reader::tagged_docs(lang_items, tag_lang_items_item, |item_doc| {
|
||||
@ -464,13 +467,13 @@ pub fn each_lang_item(cdata: Cmd, f: |ast::NodeId, uint| -> bool) -> bool {
|
||||
|
||||
pub type GetCrateDataCb<'a> = |ast::CrateNum|: 'a -> Rc<crate_metadata>;
|
||||
|
||||
fn each_child_of_item_or_crate(intr: Rc<IdentInterner>,
|
||||
cdata: Cmd,
|
||||
item_doc: rbml::Doc,
|
||||
get_crate_data: GetCrateDataCb,
|
||||
callback: |DefLike,
|
||||
ast::Name,
|
||||
ast::Visibility|) {
|
||||
fn each_child_of_item_or_crate<F>(intr: Rc<IdentInterner>,
|
||||
cdata: Cmd,
|
||||
item_doc: rbml::Doc,
|
||||
get_crate_data: GetCrateDataCb,
|
||||
mut callback: F) where
|
||||
F: FnMut(DefLike, ast::Name, ast::Visibility),
|
||||
{
|
||||
// Iterate over all children.
|
||||
let _ = reader::tagged_docs(item_doc, tag_mod_child, |child_info_doc| {
|
||||
let child_def_id = reader::with_doc_data(child_info_doc,
|
||||
@ -583,11 +586,13 @@ fn each_child_of_item_or_crate(intr: Rc<IdentInterner>,
|
||||
}
|
||||
|
||||
/// Iterates over each child of the given item.
|
||||
pub fn each_child_of_item(intr: Rc<IdentInterner>,
|
||||
cdata: Cmd,
|
||||
id: ast::NodeId,
|
||||
get_crate_data: GetCrateDataCb,
|
||||
callback: |DefLike, ast::Name, ast::Visibility|) {
|
||||
pub fn each_child_of_item<F>(intr: Rc<IdentInterner>,
|
||||
cdata: Cmd,
|
||||
id: ast::NodeId,
|
||||
get_crate_data: GetCrateDataCb,
|
||||
callback: F) where
|
||||
F: FnMut(DefLike, ast::Name, ast::Visibility),
|
||||
{
|
||||
// Find the item.
|
||||
let root_doc = rbml::Doc::new(cdata.data());
|
||||
let items = reader::get_doc(root_doc, tag_items);
|
||||
@ -604,12 +609,12 @@ pub fn each_child_of_item(intr: Rc<IdentInterner>,
|
||||
}
|
||||
|
||||
/// Iterates over all the top-level crate items.
|
||||
pub fn each_top_level_item_of_crate(intr: Rc<IdentInterner>,
|
||||
cdata: Cmd,
|
||||
get_crate_data: GetCrateDataCb,
|
||||
callback: |DefLike,
|
||||
ast::Name,
|
||||
ast::Visibility|) {
|
||||
pub fn each_top_level_item_of_crate<F>(intr: Rc<IdentInterner>,
|
||||
cdata: Cmd,
|
||||
get_crate_data: GetCrateDataCb,
|
||||
callback: F) where
|
||||
F: FnMut(DefLike, ast::Name, ast::Visibility),
|
||||
{
|
||||
let root_doc = rbml::Doc::new(cdata.data());
|
||||
let misc_info_doc = reader::get_doc(root_doc, tag_misc_info);
|
||||
let crate_items_doc = reader::get_doc(misc_info_doc,
|
||||
@ -982,9 +987,11 @@ pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd,
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn get_item_attrs(cdata: Cmd,
|
||||
orig_node_id: ast::NodeId,
|
||||
f: |Vec<ast::Attribute>|) {
|
||||
pub fn get_item_attrs<F>(cdata: Cmd,
|
||||
orig_node_id: ast::NodeId,
|
||||
f: F) where
|
||||
F: FnOnce(Vec<ast::Attribute>),
|
||||
{
|
||||
// The attributes for a tuple struct are attached to the definition, not the ctor;
|
||||
// we assume that someone passing in a tuple struct ctor is actually wanting to
|
||||
// look at the definition
|
||||
@ -1224,7 +1231,9 @@ pub fn translate_def_id(cdata: Cmd, did: ast::DefId) -> ast::DefId {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn each_impl(cdata: Cmd, callback: |ast::DefId|) {
|
||||
pub fn each_impl<F>(cdata: Cmd, mut callback: F) where
|
||||
F: FnMut(ast::DefId),
|
||||
{
|
||||
let impls_doc = reader::get_doc(rbml::Doc::new(cdata.data()), tag_impls);
|
||||
let _ = reader::tagged_docs(impls_doc, tag_impls_impl, |impl_doc| {
|
||||
callback(item_def_id(impl_doc, cdata));
|
||||
@ -1232,9 +1241,11 @@ pub fn each_impl(cdata: Cmd, callback: |ast::DefId|) {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn each_implementation_for_type(cdata: Cmd,
|
||||
pub fn each_implementation_for_type<F>(cdata: Cmd,
|
||||
id: ast::NodeId,
|
||||
callback: |ast::DefId|) {
|
||||
mut callback: F) where
|
||||
F: FnMut(ast::DefId),
|
||||
{
|
||||
let item_doc = lookup_item(id, cdata.data());
|
||||
reader::tagged_docs(item_doc,
|
||||
tag_items_data_item_inherent_impl,
|
||||
@ -1245,9 +1256,11 @@ pub fn each_implementation_for_type(cdata: Cmd,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn each_implementation_for_trait(cdata: Cmd,
|
||||
id: ast::NodeId,
|
||||
callback: |ast::DefId|) {
|
||||
pub fn each_implementation_for_trait<F>(cdata: Cmd,
|
||||
id: ast::NodeId,
|
||||
mut callback: F) where
|
||||
F: FnMut(ast::DefId),
|
||||
{
|
||||
let item_doc = lookup_item(id, cdata.data());
|
||||
|
||||
let _ = reader::tagged_docs(item_doc,
|
||||
|
@ -493,7 +493,9 @@ fn encode_reexported_static_methods(ecx: &EncodeContext,
|
||||
/// top-level items that are sub-items of the given item. Specifically:
|
||||
///
|
||||
/// * For newtype structs, iterates through the node ID of the constructor.
|
||||
fn each_auxiliary_node_id(item: &ast::Item, callback: |NodeId| -> bool) -> bool {
|
||||
fn each_auxiliary_node_id<F>(item: &ast::Item, callback: F) -> bool where
|
||||
F: FnOnce(NodeId) -> bool,
|
||||
{
|
||||
let mut continue_ = true;
|
||||
match item.node {
|
||||
ast::ItemStruct(ref struct_def, _) => {
|
||||
@ -1579,8 +1581,10 @@ fn encode_info_for_items(ecx: &EncodeContext,
|
||||
|
||||
// Path and definition ID indexing
|
||||
|
||||
fn encode_index<T: Hash>(rbml_w: &mut Encoder, index: Vec<entry<T>>,
|
||||
write_fn: |&mut SeekableMemWriter, &T|) {
|
||||
fn encode_index<T, F>(rbml_w: &mut Encoder, index: Vec<entry<T>>, mut write_fn: F) where
|
||||
F: FnMut(&mut SeekableMemWriter, &T),
|
||||
T: Hash,
|
||||
{
|
||||
let mut buckets: Vec<Vec<entry<T>>> = Vec::from_fn(256, |_| Vec::new());
|
||||
for elt in index.into_iter() {
|
||||
let h = hash::hash(&elt.val) as uint;
|
||||
|
@ -42,7 +42,9 @@ pub struct FileSearch<'a> {
|
||||
}
|
||||
|
||||
impl<'a> FileSearch<'a> {
|
||||
pub fn for_each_lib_search_path(&self, f: |&Path| -> FileMatch) {
|
||||
pub fn for_each_lib_search_path<F>(&self, mut f: F) where
|
||||
F: FnMut(&Path) -> FileMatch,
|
||||
{
|
||||
let mut visited_dirs = HashSet::new();
|
||||
let mut found = false;
|
||||
|
||||
|
@ -89,7 +89,10 @@ fn next_byte(st: &mut PState) -> u8 {
|
||||
return b;
|
||||
}
|
||||
|
||||
fn scan<R>(st: &mut PState, is_last: |char| -> bool, op: |&[u8]| -> R) -> R {
|
||||
fn scan<R, F, G>(st: &mut PState, mut is_last: F, op: G) -> R where
|
||||
F: FnMut(char) -> bool,
|
||||
G: FnOnce(&[u8]) -> R,
|
||||
{
|
||||
let start_pos = st.pos;
|
||||
debug!("scan: '{}' (start)", st.data[st.pos] as char);
|
||||
while !is_last(st.data[st.pos] as char) {
|
||||
@ -110,7 +113,9 @@ pub fn parse_name(st: &mut PState, last: char) -> ast::Name {
|
||||
parse_name_(st, |a| is_last(last, a) )
|
||||
}
|
||||
|
||||
fn parse_name_(st: &mut PState, is_last: |char| -> bool) -> ast::Name {
|
||||
fn parse_name_<F>(st: &mut PState, is_last: F) -> ast::Name where
|
||||
F: FnMut(char) -> bool,
|
||||
{
|
||||
scan(st, is_last, |bytes| {
|
||||
token::intern(str::from_utf8(bytes).unwrap())
|
||||
})
|
||||
@ -234,9 +239,10 @@ fn parse_trait_store(st: &mut PState, conv: conv_did) -> ty::TraitStore {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_vec_per_param_space<'a, 'tcx, T>(st: &mut PState<'a, 'tcx>,
|
||||
f: |&mut PState<'a, 'tcx>| -> T)
|
||||
-> VecPerParamSpace<T>
|
||||
fn parse_vec_per_param_space<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>,
|
||||
mut f: F)
|
||||
-> VecPerParamSpace<T> where
|
||||
F: FnMut(&mut PState<'a, 'tcx>) -> T,
|
||||
{
|
||||
let mut r = VecPerParamSpace::empty();
|
||||
for &space in subst::ParamSpace::all().iter() {
|
||||
@ -350,8 +356,9 @@ fn parse_scope(st: &mut PState) -> region::CodeExtent {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_opt<'a, 'tcx, T>(st: &mut PState<'a, 'tcx>, f: |&mut PState<'a, 'tcx>| -> T)
|
||||
-> Option<T> {
|
||||
fn parse_opt<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>, f: F) -> Option<T> where
|
||||
F: FnOnce(&mut PState<'a, 'tcx>) -> T,
|
||||
{
|
||||
match next(st) {
|
||||
'n' => None,
|
||||
's' => Some(f(st)),
|
||||
|
@ -86,7 +86,9 @@ fn enc_mt<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
|
||||
enc_ty(w, cx, mt.ty);
|
||||
}
|
||||
|
||||
fn enc_opt<T>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: |&mut SeekableMemWriter, T|) {
|
||||
fn enc_opt<T, F>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: F) where
|
||||
F: FnOnce(&mut SeekableMemWriter, T),
|
||||
{
|
||||
match t {
|
||||
None => mywrite!(w, "n"),
|
||||
Some(v) => {
|
||||
@ -96,10 +98,12 @@ fn enc_opt<T>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: |&mut SeekableMemW
|
||||
}
|
||||
}
|
||||
|
||||
fn enc_vec_per_param_space<'a, 'tcx, T>(w: &mut SeekableMemWriter,
|
||||
cx: &ctxt<'a, 'tcx>,
|
||||
v: &VecPerParamSpace<T>,
|
||||
op: |&mut SeekableMemWriter, &ctxt<'a, 'tcx>, &T|) {
|
||||
fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut SeekableMemWriter,
|
||||
cx: &ctxt<'a, 'tcx>,
|
||||
v: &VecPerParamSpace<T>,
|
||||
mut op: F) where
|
||||
F: FnMut(&mut SeekableMemWriter, &ctxt<'a, 'tcx>, &T),
|
||||
{
|
||||
for &space in subst::ParamSpace::all().iter() {
|
||||
mywrite!(w, "[");
|
||||
for t in v.get_slice(space).iter() {
|
||||
|
@ -680,9 +680,8 @@ pub fn encode_unboxed_closure_kind(ebml_w: &mut Encoder,
|
||||
}
|
||||
|
||||
pub trait vtable_decoder_helpers<'tcx> {
|
||||
fn read_vec_per_param_space<T>(&mut self,
|
||||
f: |&mut Self| -> T)
|
||||
-> VecPerParamSpace<T>;
|
||||
fn read_vec_per_param_space<T, F>(&mut self, f: F) -> VecPerParamSpace<T> where
|
||||
F: FnMut(&mut Self) -> T;
|
||||
fn read_vtable_res_with_key(&mut self,
|
||||
tcx: &ty::ctxt<'tcx>,
|
||||
cdata: &cstore::crate_metadata)
|
||||
@ -699,9 +698,8 @@ pub trait vtable_decoder_helpers<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||
fn read_vec_per_param_space<T>(&mut self,
|
||||
f: |&mut reader::Decoder<'a>| -> T)
|
||||
-> VecPerParamSpace<T>
|
||||
fn read_vec_per_param_space<T, F>(&mut self, mut f: F) -> VecPerParamSpace<T> where
|
||||
F: FnMut(&mut reader::Decoder<'a>) -> T,
|
||||
{
|
||||
let types = self.read_to_vec(|this| Ok(f(this))).unwrap();
|
||||
let selfs = self.read_to_vec(|this| Ok(f(this))).unwrap();
|
||||
@ -793,9 +791,11 @@ impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||
// ___________________________________________________________________________
|
||||
//
|
||||
|
||||
fn encode_vec_per_param_space<T>(rbml_w: &mut Encoder,
|
||||
v: &subst::VecPerParamSpace<T>,
|
||||
f: |&mut Encoder, &T|) {
|
||||
fn encode_vec_per_param_space<T, F>(rbml_w: &mut Encoder,
|
||||
v: &subst::VecPerParamSpace<T>,
|
||||
mut f: F) where
|
||||
F: FnMut(&mut Encoder, &T),
|
||||
{
|
||||
for &space in subst::ParamSpace::all().iter() {
|
||||
rbml_w.emit_from_vec(v.get_slice(space),
|
||||
|rbml_w, n| Ok(f(rbml_w, n))).unwrap();
|
||||
@ -1124,14 +1124,16 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
|
||||
}
|
||||
|
||||
trait write_tag_and_id {
|
||||
fn tag(&mut self, tag_id: c::astencode_tag, f: |&mut Self|);
|
||||
fn tag<F>(&mut self, tag_id: c::astencode_tag, f: F) where F: FnOnce(&mut Self);
|
||||
fn id(&mut self, id: ast::NodeId);
|
||||
}
|
||||
|
||||
impl<'a> write_tag_and_id for Encoder<'a> {
|
||||
fn tag(&mut self,
|
||||
tag_id: c::astencode_tag,
|
||||
f: |&mut Encoder<'a>|) {
|
||||
fn tag<F>(&mut self,
|
||||
tag_id: c::astencode_tag,
|
||||
f: F) where
|
||||
F: FnOnce(&mut Encoder<'a>),
|
||||
{
|
||||
self.start_tag(tag_id as uint);
|
||||
f(self);
|
||||
self.end_tag();
|
||||
|
@ -24,16 +24,22 @@ struct CheckCrateVisitor<'a, 'tcx: 'a> {
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
|
||||
fn with_const(&mut self, in_const: bool, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
|
||||
fn with_const<F>(&mut self, in_const: bool, f: F) where
|
||||
F: FnOnce(&mut CheckCrateVisitor<'a, 'tcx>),
|
||||
{
|
||||
let was_const = self.in_const;
|
||||
self.in_const = in_const;
|
||||
f(self);
|
||||
self.in_const = was_const;
|
||||
}
|
||||
fn inside_const(&mut self, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
|
||||
fn inside_const<F>(&mut self, f: F) where
|
||||
F: FnOnce(&mut CheckCrateVisitor<'a, 'tcx>),
|
||||
{
|
||||
self.with_const(true, f);
|
||||
}
|
||||
fn outside_const(&mut self, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
|
||||
fn outside_const<F>(&mut self, f: F) where
|
||||
F: FnOnce(&mut CheckCrateVisitor<'a, 'tcx>),
|
||||
{
|
||||
self.with_const(false, f);
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,9 @@ impl<'a, 'v> Visitor<'v> for CheckLoopVisitor<'a> {
|
||||
}
|
||||
|
||||
impl<'a> CheckLoopVisitor<'a> {
|
||||
fn with_context(&mut self, cx: Context, f: |&mut CheckLoopVisitor<'a>|) {
|
||||
fn with_context<F>(&mut self, cx: Context, f: F) where
|
||||
F: FnOnce(&mut CheckLoopVisitor<'a>),
|
||||
{
|
||||
let old_cx = self.cx;
|
||||
self.cx = cx;
|
||||
f(self);
|
||||
|
@ -980,7 +980,9 @@ fn check_fn(cx: &mut MatchCheckCtxt,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_refutable<A>(cx: &MatchCheckCtxt, pat: &Pat, refutable: |&Pat| -> A) -> Option<A> {
|
||||
fn is_refutable<A, F>(cx: &MatchCheckCtxt, pat: &Pat, refutable: F) -> Option<A> where
|
||||
F: FnOnce(&Pat) -> A,
|
||||
{
|
||||
let pats = Matrix(vec!(vec!(pat)));
|
||||
match is_useful(cx, &pats, &[DUMMY_WILD_PAT], ConstructWitness) {
|
||||
UsefulWithWitness(pats) => {
|
||||
|
@ -85,7 +85,9 @@ pub fn check_crate(tcx: &ty::ctxt) {
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> CheckStaticVisitor<'a, 'tcx> {
|
||||
fn with_mode(&mut self, mode: Mode, f: |&mut CheckStaticVisitor<'a, 'tcx>|) {
|
||||
fn with_mode<F>(&mut self, mode: Mode, f: F) where
|
||||
F: FnOnce(&mut CheckStaticVisitor<'a, 'tcx>),
|
||||
{
|
||||
let old = self.mode;
|
||||
self.mode = mode;
|
||||
f(self);
|
||||
|
@ -280,10 +280,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
|
||||
}
|
||||
|
||||
|
||||
pub fn each_bit_on_entry(&self,
|
||||
id: ast::NodeId,
|
||||
f: |uint| -> bool)
|
||||
-> bool {
|
||||
pub fn each_bit_on_entry<F>(&self, id: ast::NodeId, f: F) -> bool where
|
||||
F: FnMut(uint) -> bool,
|
||||
{
|
||||
//! Iterates through each bit that is set on entry to `id`.
|
||||
//! Only useful after `propagate()` has been called.
|
||||
if !self.has_bitset_for_nodeid(id) {
|
||||
@ -293,11 +292,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
|
||||
self.each_bit_for_node(Entry, cfgidx, f)
|
||||
}
|
||||
|
||||
pub fn each_bit_for_node(&self,
|
||||
e: EntryOrExit,
|
||||
cfgidx: CFGIndex,
|
||||
f: |uint| -> bool)
|
||||
-> bool {
|
||||
pub fn each_bit_for_node<F>(&self, e: EntryOrExit, cfgidx: CFGIndex, f: F) -> bool where
|
||||
F: FnMut(uint) -> bool,
|
||||
{
|
||||
//! Iterates through each bit that is set on entry/exit to `cfgidx`.
|
||||
//! Only useful after `propagate()` has been called.
|
||||
|
||||
@ -324,8 +321,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
|
||||
self.each_bit(slice, f)
|
||||
}
|
||||
|
||||
pub fn each_gen_bit(&self, id: ast::NodeId, f: |uint| -> bool)
|
||||
-> bool {
|
||||
pub fn each_gen_bit<F>(&self, id: ast::NodeId, f: F) -> bool where
|
||||
F: FnMut(uint) -> bool,
|
||||
{
|
||||
//! Iterates through each bit in the gen set for `id`.
|
||||
if !self.has_bitset_for_nodeid(id) {
|
||||
return true;
|
||||
@ -345,7 +343,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
|
||||
self.each_bit(gens, f)
|
||||
}
|
||||
|
||||
fn each_bit(&self, words: &[uint], f: |uint| -> bool) -> bool {
|
||||
fn each_bit<F>(&self, words: &[uint], mut f: F) -> bool where
|
||||
F: FnMut(uint) -> bool,
|
||||
{
|
||||
//! Helper for iterating over the bits in a bit set.
|
||||
//! Returns false on the first call to `f` that returns false;
|
||||
//! if all calls to `f` return true, then returns true.
|
||||
|
@ -61,7 +61,9 @@ pub enum MethodProvenance {
|
||||
}
|
||||
|
||||
impl MethodProvenance {
|
||||
pub fn map(self, f: |ast::DefId| -> ast::DefId) -> MethodProvenance {
|
||||
pub fn map<F>(self, f: F) -> MethodProvenance where
|
||||
F: FnOnce(ast::DefId) -> ast::DefId,
|
||||
{
|
||||
match self {
|
||||
FromTrait(did) => FromTrait(f(did)),
|
||||
FromImpl(did) => FromImpl(f(did))
|
||||
|
@ -221,39 +221,43 @@ impl<N,E> Graph<N,E> {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Iterating over nodes, edges
|
||||
|
||||
pub fn each_node<'a>(&'a self, f: |NodeIndex, &'a Node<N>| -> bool) -> bool {
|
||||
pub fn each_node<'a, F>(&'a self, mut f: F) -> bool where
|
||||
F: FnMut(NodeIndex, &'a Node<N>) -> bool,
|
||||
{
|
||||
//! Iterates over all edges defined in the graph.
|
||||
self.nodes.iter().enumerate().all(|(i, node)| f(NodeIndex(i), node))
|
||||
}
|
||||
|
||||
pub fn each_edge<'a>(&'a self, f: |EdgeIndex, &'a Edge<E>| -> bool) -> bool {
|
||||
pub fn each_edge<'a, F>(&'a self, mut f: F) -> bool where
|
||||
F: FnMut(EdgeIndex, &'a Edge<E>) -> bool,
|
||||
{
|
||||
//! Iterates over all edges defined in the graph
|
||||
self.edges.iter().enumerate().all(|(i, edge)| f(EdgeIndex(i), edge))
|
||||
}
|
||||
|
||||
pub fn each_outgoing_edge<'a>(&'a self,
|
||||
source: NodeIndex,
|
||||
f: |EdgeIndex, &'a Edge<E>| -> bool)
|
||||
-> bool {
|
||||
pub fn each_outgoing_edge<'a, F>(&'a self, source: NodeIndex, f: F) -> bool where
|
||||
F: FnMut(EdgeIndex, &'a Edge<E>) -> bool,
|
||||
{
|
||||
//! Iterates over all outgoing edges from the node `from`
|
||||
|
||||
self.each_adjacent_edge(source, Outgoing, f)
|
||||
}
|
||||
|
||||
pub fn each_incoming_edge<'a>(&'a self,
|
||||
target: NodeIndex,
|
||||
f: |EdgeIndex, &'a Edge<E>| -> bool)
|
||||
-> bool {
|
||||
pub fn each_incoming_edge<'a, F>(&'a self, target: NodeIndex, f: F) -> bool where
|
||||
F: FnMut(EdgeIndex, &'a Edge<E>) -> bool,
|
||||
{
|
||||
//! Iterates over all incoming edges to the node `target`
|
||||
|
||||
self.each_adjacent_edge(target, Incoming, f)
|
||||
}
|
||||
|
||||
pub fn each_adjacent_edge<'a>(&'a self,
|
||||
node: NodeIndex,
|
||||
dir: Direction,
|
||||
f: |EdgeIndex, &'a Edge<E>| -> bool)
|
||||
-> bool {
|
||||
pub fn each_adjacent_edge<'a, F>(&'a self,
|
||||
node: NodeIndex,
|
||||
dir: Direction,
|
||||
mut f: F)
|
||||
-> bool where
|
||||
F: FnMut(EdgeIndex, &'a Edge<E>) -> bool,
|
||||
{
|
||||
//! Iterates over all edges adjacent to the node `node`
|
||||
//! in the direction `dir` (either `Outgoing` or `Incoming)
|
||||
|
||||
@ -277,11 +281,9 @@ impl<N,E> Graph<N,E> {
|
||||
// variables or other bitsets. This method facilitates such a
|
||||
// computation.
|
||||
|
||||
pub fn iterate_until_fixed_point<'a>(&'a self,
|
||||
op: |iter_index: uint,
|
||||
edge_index: EdgeIndex,
|
||||
edge: &'a Edge<E>|
|
||||
-> bool) {
|
||||
pub fn iterate_until_fixed_point<'a, F>(&'a self, mut op: F) where
|
||||
F: FnMut(uint, EdgeIndex, &'a Edge<E>) -> bool,
|
||||
{
|
||||
let mut iteration = 0;
|
||||
let mut changed = true;
|
||||
while changed {
|
||||
@ -294,7 +296,9 @@ impl<N,E> Graph<N,E> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn each_edge_index(max_edge_index: EdgeIndex, f: |EdgeIndex| -> bool) {
|
||||
pub fn each_edge_index<F>(max_edge_index: EdgeIndex, mut f: F) where
|
||||
F: FnMut(EdgeIndex) -> bool,
|
||||
{
|
||||
let mut i = 0;
|
||||
let n = max_edge_index.get();
|
||||
while i < n {
|
||||
|
@ -194,8 +194,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unpack_actual_value<T>(&self, a: Ty<'tcx>, f: |&ty::sty<'tcx>| -> T)
|
||||
-> T {
|
||||
pub fn unpack_actual_value<T, F>(&self, a: Ty<'tcx>, f: F) -> T where
|
||||
F: FnOnce(&ty::sty<'tcx>) -> T,
|
||||
{
|
||||
match resolve_type(self.get_ref().infcx, None,
|
||||
a, try_resolve_tvar_shallow) {
|
||||
Ok(t) => {
|
||||
@ -458,13 +459,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
|| AutoUnsafe(b_mutbl, None))
|
||||
}
|
||||
|
||||
fn coerce_object(&self,
|
||||
a: Ty<'tcx>,
|
||||
sty_a: &ty::sty<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
b_mutbl: ast::Mutability,
|
||||
mk_ty: |Ty<'tcx>| -> Ty<'tcx>,
|
||||
mk_adjust: || -> ty::AutoRef<'tcx>) -> CoerceResult<'tcx>
|
||||
fn coerce_object<F, G>(&self,
|
||||
a: Ty<'tcx>,
|
||||
sty_a: &ty::sty<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
b_mutbl: ast::Mutability,
|
||||
mk_ty: F,
|
||||
mk_adjust: G) -> CoerceResult<'tcx> where
|
||||
F: FnOnce(Ty<'tcx>) -> Ty<'tcx>,
|
||||
G: FnOnce() -> ty::AutoRef<'tcx>,
|
||||
{
|
||||
let tcx = self.get_ref().infcx.tcx;
|
||||
|
||||
|
@ -426,11 +426,9 @@ fn is_var_in_set(new_vars: &[ty::RegionVid], r: ty::Region) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_regions_in<'tcx, T>(tcx: &ty::ctxt<'tcx>,
|
||||
value: &T,
|
||||
fldr: |ty::Region, ty::DebruijnIndex| -> ty::Region)
|
||||
-> T
|
||||
where T: HigherRankedFoldable<'tcx>
|
||||
fn fold_regions_in<'tcx, T, F>(tcx: &ty::ctxt<'tcx>, value: &T, mut fldr: F) -> T where
|
||||
T: HigherRankedFoldable<'tcx>,
|
||||
F: FnMut(ty::Region, ty::DebruijnIndex) -> ty::Region,
|
||||
{
|
||||
value.fold_contents(&mut ty_fold::RegionFolder::new(tcx, |region, current_depth| {
|
||||
// we should only be encountering "escaping" late-bound regions here,
|
||||
|
@ -477,14 +477,17 @@ pub fn resolve_region(cx: &InferCtxt, r: ty::Region, modes: uint)
|
||||
}
|
||||
|
||||
trait then<'tcx> {
|
||||
fn then<T:Clone>(&self, f: || -> Result<T,ty::type_err<'tcx>>)
|
||||
-> Result<T,ty::type_err<'tcx>>;
|
||||
fn then<T, F>(&self, f: F) -> Result<T, ty::type_err<'tcx>> where
|
||||
T: Clone,
|
||||
F: FnOnce() -> Result<T, ty::type_err<'tcx>>;
|
||||
}
|
||||
|
||||
impl<'tcx> then<'tcx> for ures<'tcx> {
|
||||
fn then<T:Clone>(&self, f: || -> Result<T,ty::type_err<'tcx>>)
|
||||
-> Result<T,ty::type_err<'tcx>> {
|
||||
self.and_then(|_i| f())
|
||||
fn then<T, F>(&self, f: F) -> Result<T, ty::type_err<'tcx>> where
|
||||
T: Clone,
|
||||
F: FnOnce() -> Result<T, ty::type_err<'tcx>>,
|
||||
{
|
||||
self.and_then(move |_| f())
|
||||
}
|
||||
}
|
||||
|
||||
@ -502,12 +505,15 @@ impl<'tcx, T> ToUres<'tcx> for cres<'tcx, T> {
|
||||
}
|
||||
|
||||
trait CresCompare<'tcx, T> {
|
||||
fn compare(&self, t: T, f: || -> ty::type_err<'tcx>) -> cres<'tcx, T>;
|
||||
fn compare<F>(&self, t: T, f: F) -> cres<'tcx, T> where
|
||||
F: FnOnce() -> ty::type_err<'tcx>;
|
||||
}
|
||||
|
||||
impl<'tcx, T:Clone + PartialEq> CresCompare<'tcx, T> for cres<'tcx, T> {
|
||||
fn compare(&self, t: T, f: || -> ty::type_err<'tcx>) -> cres<'tcx, T> {
|
||||
(*self).clone().and_then(|s| {
|
||||
fn compare<F>(&self, t: T, f: F) -> cres<'tcx, T> where
|
||||
F: FnOnce() -> ty::type_err<'tcx>,
|
||||
{
|
||||
(*self).clone().and_then(move |s| {
|
||||
if s == t {
|
||||
(*self).clone()
|
||||
} else {
|
||||
@ -616,7 +622,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
/// Execute `f` and commit the bindings
|
||||
pub fn commit_unconditionally<R>(&self, f: || -> R) -> R {
|
||||
pub fn commit_unconditionally<R, F>(&self, f: F) -> R where
|
||||
F: FnOnce() -> R,
|
||||
{
|
||||
debug!("commit()");
|
||||
let snapshot = self.start_snapshot();
|
||||
let r = f();
|
||||
@ -625,12 +633,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
/// Execute `f` and commit the bindings if successful
|
||||
pub fn commit_if_ok<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> {
|
||||
self.commit_unconditionally(|| self.try(|| f()))
|
||||
pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where
|
||||
F: FnOnce() -> Result<T, E>
|
||||
{
|
||||
self.commit_unconditionally(move || self.try(move || f()))
|
||||
}
|
||||
|
||||
/// Execute `f`, unroll bindings on panic
|
||||
pub fn try<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> {
|
||||
pub fn try<T, E, F>(&self, f: F) -> Result<T, E> where
|
||||
F: FnOnce() -> Result<T, E>
|
||||
{
|
||||
debug!("try()");
|
||||
let snapshot = self.start_snapshot();
|
||||
let r = f();
|
||||
@ -647,7 +659,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
/// Execute `f` then unroll any bindings it creates
|
||||
pub fn probe<R>(&self, f: || -> R) -> R {
|
||||
pub fn probe<R, F>(&self, f: F) -> R where
|
||||
F: FnOnce() -> R,
|
||||
{
|
||||
debug!("probe()");
|
||||
let snapshot = self.start_snapshot();
|
||||
let r = f();
|
||||
@ -902,22 +916,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
// in this case. The typechecker should only ever report type errors involving mismatched
|
||||
// types using one of these four methods, and should not call span_err directly for such
|
||||
// errors.
|
||||
pub fn type_error_message_str(&self,
|
||||
sp: Span,
|
||||
mk_msg: |Option<String>, String| -> String,
|
||||
actual_ty: String,
|
||||
err: Option<&ty::type_err<'tcx>>) {
|
||||
pub fn type_error_message_str<M>(&self,
|
||||
sp: Span,
|
||||
mk_msg: M,
|
||||
actual_ty: String,
|
||||
err: Option<&ty::type_err<'tcx>>) where
|
||||
M: FnOnce(Option<String>, String) -> String,
|
||||
{
|
||||
self.type_error_message_str_with_expected(sp, mk_msg, None, actual_ty, err)
|
||||
}
|
||||
|
||||
pub fn type_error_message_str_with_expected(&self,
|
||||
sp: Span,
|
||||
mk_msg: |Option<String>,
|
||||
String|
|
||||
-> String,
|
||||
expected_ty: Option<Ty<'tcx>>,
|
||||
actual_ty: String,
|
||||
err: Option<&ty::type_err<'tcx>>) {
|
||||
pub fn type_error_message_str_with_expected<M>(&self,
|
||||
sp: Span,
|
||||
mk_msg: M,
|
||||
expected_ty: Option<Ty<'tcx>>,
|
||||
actual_ty: String,
|
||||
err: Option<&ty::type_err<'tcx>>) where
|
||||
M: FnOnce(Option<String>, String) -> String,
|
||||
{
|
||||
debug!("hi! expected_ty = {}, actual_ty = {}", expected_ty, actual_ty);
|
||||
|
||||
let resolved_expected = expected_ty.map(|e_ty| {
|
||||
@ -942,11 +958,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_error_message(&self,
|
||||
sp: Span,
|
||||
mk_msg: |String| -> String,
|
||||
actual_ty: Ty<'tcx>,
|
||||
err: Option<&ty::type_err<'tcx>>) {
|
||||
pub fn type_error_message<M>(&self,
|
||||
sp: Span,
|
||||
mk_msg: M,
|
||||
actual_ty: Ty<'tcx>,
|
||||
err: Option<&ty::type_err<'tcx>>) where
|
||||
M: FnOnce(String) -> String,
|
||||
{
|
||||
let actual_ty = self.resolve_type_vars_if_possible(actual_ty);
|
||||
|
||||
// Don't report an error if actual type is ty_err.
|
||||
@ -954,7 +972,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
return;
|
||||
}
|
||||
|
||||
self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_string(actual_ty), err);
|
||||
self.type_error_message_str(sp,
|
||||
move |_e, a| { mk_msg(a) },
|
||||
self.ty_to_string(actual_ty), err);
|
||||
}
|
||||
|
||||
pub fn report_mismatched_types(&self,
|
||||
|
@ -569,15 +569,15 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn combine_vars(&self,
|
||||
t: CombineMapType,
|
||||
a: Region,
|
||||
b: Region,
|
||||
origin: SubregionOrigin<'tcx>,
|
||||
relate: |this: &RegionVarBindings<'a, 'tcx>,
|
||||
old_r: Region,
|
||||
new_r: Region|)
|
||||
-> Region {
|
||||
pub fn combine_vars<F>(&self,
|
||||
t: CombineMapType,
|
||||
a: Region,
|
||||
b: Region,
|
||||
origin: SubregionOrigin<'tcx>,
|
||||
mut relate: F)
|
||||
-> Region where
|
||||
F: FnMut(&RegionVarBindings<'a, 'tcx>, Region, Region),
|
||||
{
|
||||
let vars = TwoRegions { a: a, b: b };
|
||||
match self.combine_map(t).borrow().get(&vars) {
|
||||
Some(&c) => {
|
||||
@ -1539,9 +1539,9 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn iterate_until_fixed_point(&self,
|
||||
tag: &str,
|
||||
body: |constraint: &Constraint| -> bool) {
|
||||
fn iterate_until_fixed_point<F>(&self, tag: &str, mut body: F) where
|
||||
F: FnMut(&Constraint) -> bool,
|
||||
{
|
||||
let mut iteration = 0u;
|
||||
let mut changed = true;
|
||||
while changed {
|
||||
|
@ -54,11 +54,12 @@ impl<'a, 'tcx> TypeSkolemizer<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn skolemize(&mut self,
|
||||
opt_ty: Option<Ty<'tcx>>,
|
||||
key: ty::InferTy,
|
||||
skolemizer: |uint| -> ty::InferTy)
|
||||
-> Ty<'tcx>
|
||||
fn skolemize<F>(&mut self,
|
||||
opt_ty: Option<Ty<'tcx>>,
|
||||
key: ty::InferTy,
|
||||
skolemizer: F)
|
||||
-> Ty<'tcx> where
|
||||
F: FnOnce(uint) -> ty::InferTy,
|
||||
{
|
||||
match opt_ty {
|
||||
Some(ty) => { return ty.fold_with(self); }
|
||||
|
@ -616,9 +616,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
self.ir.variable(node_id, span)
|
||||
}
|
||||
|
||||
fn pat_bindings(&mut self,
|
||||
pat: &ast::Pat,
|
||||
f: |&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId|) {
|
||||
fn pat_bindings<F>(&mut self, pat: &ast::Pat, mut f: F) where
|
||||
F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId),
|
||||
{
|
||||
pat_util::pat_bindings(&self.ir.tcx.def_map, pat, |_bm, p_id, sp, _n| {
|
||||
let ln = self.live_node(p_id, sp);
|
||||
let var = self.variable(p_id, sp);
|
||||
@ -626,9 +626,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
fn arm_pats_bindings(&mut self,
|
||||
pat: Option<&ast::Pat>,
|
||||
f: |&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId|) {
|
||||
fn arm_pats_bindings<F>(&mut self, pat: Option<&ast::Pat>, f: F) where
|
||||
F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId),
|
||||
{
|
||||
match pat {
|
||||
Some(pat) => {
|
||||
self.pat_bindings(pat, f);
|
||||
@ -691,10 +691,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
self.assigned_on_entry(successor, var)
|
||||
}
|
||||
|
||||
fn indices2(&mut self,
|
||||
ln: LiveNode,
|
||||
succ_ln: LiveNode,
|
||||
op: |&mut Liveness<'a, 'tcx>, uint, uint|) {
|
||||
fn indices2<F>(&mut self, ln: LiveNode, succ_ln: LiveNode, mut op: F) where
|
||||
F: FnMut(&mut Liveness<'a, 'tcx>, uint, uint),
|
||||
{
|
||||
let node_base_idx = self.idx(ln, Variable(0u));
|
||||
let succ_base_idx = self.idx(succ_ln, Variable(0u));
|
||||
for var_idx in range(0u, self.ir.num_vars) {
|
||||
@ -702,10 +701,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn write_vars(&self,
|
||||
wr: &mut io::Writer,
|
||||
ln: LiveNode,
|
||||
test: |uint| -> LiveNode) -> io::IoResult<()> {
|
||||
fn write_vars<F>(&self,
|
||||
wr: &mut io::Writer,
|
||||
ln: LiveNode,
|
||||
mut test: F)
|
||||
-> io::IoResult<()> where
|
||||
F: FnMut(uint) -> LiveNode,
|
||||
{
|
||||
let node_base_idx = self.idx(ln, Variable(0));
|
||||
for var_idx in range(0u, self.ir.num_vars) {
|
||||
let idx = node_base_idx + var_idx;
|
||||
@ -1408,12 +1410,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
cond_ln
|
||||
}
|
||||
|
||||
fn with_loop_nodes<R>(&mut self,
|
||||
loop_node_id: NodeId,
|
||||
break_ln: LiveNode,
|
||||
cont_ln: LiveNode,
|
||||
f: |&mut Liveness<'a, 'tcx>| -> R)
|
||||
-> R {
|
||||
fn with_loop_nodes<R, F>(&mut self,
|
||||
loop_node_id: NodeId,
|
||||
break_ln: LiveNode,
|
||||
cont_ln: LiveNode,
|
||||
f: F)
|
||||
-> R where
|
||||
F: FnOnce(&mut Liveness<'a, 'tcx>) -> R,
|
||||
{
|
||||
debug!("with_loop_nodes: {} {}", loop_node_id, break_ln.get());
|
||||
self.loop_scope.push(loop_node_id);
|
||||
self.break_ln.insert(loop_node_id, break_ln);
|
||||
|
@ -1142,12 +1142,11 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
||||
})
|
||||
}
|
||||
|
||||
// FIXME(#19596) unbox `op`
|
||||
pub fn cat_pattern(&self,
|
||||
cmt: cmt<'tcx>,
|
||||
pat: &ast::Pat,
|
||||
op: |&MemCategorizationContext<'t,TYPER>,
|
||||
cmt<'tcx>,
|
||||
&ast::Pat|)
|
||||
op: |&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat|)
|
||||
-> McResult<()> {
|
||||
// Here, `cmt` is the categorization for the value being
|
||||
// matched and pat is the pattern it is being matched against.
|
||||
|
@ -91,9 +91,9 @@ pub fn pat_is_binding_or_wild(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
|
||||
|
||||
/// Call `it` on every "binding" in a pattern, e.g., on `a` in
|
||||
/// `match foo() { Some(a) => (), None => () }`
|
||||
pub fn pat_bindings(dm: &resolve::DefMap,
|
||||
pat: &ast::Pat,
|
||||
it: |ast::BindingMode, ast::NodeId, Span, &ast::SpannedIdent|) {
|
||||
pub fn pat_bindings<I>(dm: &resolve::DefMap, pat: &ast::Pat, mut it: I) where
|
||||
I: FnMut(ast::BindingMode, ast::NodeId, Span, &ast::SpannedIdent),
|
||||
{
|
||||
walk_pat(pat, |p| {
|
||||
match p.node {
|
||||
ast::PatIdent(binding_mode, ref pth, _) if pat_is_binding(dm, p) => {
|
||||
|
@ -62,7 +62,9 @@ impl CodeExtent {
|
||||
|
||||
/// Maps this scope to a potentially new one according to the
|
||||
/// NodeId transformer `f_id`.
|
||||
pub fn map_id(&self, f_id: |ast::NodeId| -> ast::NodeId) -> CodeExtent {
|
||||
pub fn map_id<F>(&self, f_id: F) -> CodeExtent where
|
||||
F: FnOnce(ast::NodeId) -> ast::NodeId,
|
||||
{
|
||||
match *self {
|
||||
CodeExtent::Misc(node_id) => CodeExtent::Misc(f_id(node_id)),
|
||||
}
|
||||
|
@ -1837,10 +1837,12 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
|
||||
/// Constructs the reduced graph for one foreign item.
|
||||
fn build_reduced_graph_for_foreign_item(&mut self,
|
||||
foreign_item: &ForeignItem,
|
||||
parent: ReducedGraphParent,
|
||||
f: |&mut Resolver|) {
|
||||
fn build_reduced_graph_for_foreign_item<F>(&mut self,
|
||||
foreign_item: &ForeignItem,
|
||||
parent: ReducedGraphParent,
|
||||
f: F) where
|
||||
F: FnOnce(&mut Resolver),
|
||||
{
|
||||
let name = foreign_item.ident.name;
|
||||
let is_public = foreign_item.vis == ast::Public;
|
||||
let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
|
||||
@ -3970,7 +3972,9 @@ impl<'a> Resolver<'a> {
|
||||
// generate a fake "implementation scope" containing all the
|
||||
// implementations thus found, for compatibility with old resolve pass.
|
||||
|
||||
fn with_scope(&mut self, name: Option<Name>, f: |&mut Resolver|) {
|
||||
fn with_scope<F>(&mut self, name: Option<Name>, f: F) where
|
||||
F: FnOnce(&mut Resolver),
|
||||
{
|
||||
let orig_module = self.current_module.clone();
|
||||
|
||||
// Move down in the graph.
|
||||
@ -4373,9 +4377,9 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn with_type_parameter_rib(&mut self,
|
||||
type_parameters: TypeParameters,
|
||||
f: |&mut Resolver|) {
|
||||
fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F) where
|
||||
F: FnOnce(&mut Resolver),
|
||||
{
|
||||
match type_parameters {
|
||||
HasTypeParameters(generics, space, node_id, rib_kind) => {
|
||||
let mut function_type_rib = Rib::new(rib_kind);
|
||||
@ -4422,13 +4426,17 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn with_label_rib(&mut self, f: |&mut Resolver|) {
|
||||
fn with_label_rib<F>(&mut self, f: F) where
|
||||
F: FnOnce(&mut Resolver),
|
||||
{
|
||||
self.label_ribs.push(Rib::new(NormalRibKind));
|
||||
f(self);
|
||||
self.label_ribs.pop();
|
||||
}
|
||||
|
||||
fn with_constant_rib(&mut self, f: |&mut Resolver|) {
|
||||
fn with_constant_rib<F>(&mut self, f: F) where
|
||||
F: FnOnce(&mut Resolver),
|
||||
{
|
||||
self.value_ribs.push(Rib::new(ConstantItemRibKind));
|
||||
self.type_ribs.push(Rib::new(ConstantItemRibKind));
|
||||
f(self);
|
||||
@ -4676,7 +4684,9 @@ impl<'a> Resolver<'a> {
|
||||
method.pe_body());
|
||||
}
|
||||
|
||||
fn with_current_self_type<T>(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T {
|
||||
fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T where
|
||||
F: FnOnce(&mut Resolver) -> T,
|
||||
{
|
||||
// Handle nested impls (inside fn bodies)
|
||||
let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
|
||||
let result = f(self);
|
||||
@ -4684,9 +4694,11 @@ impl<'a> Resolver<'a> {
|
||||
result
|
||||
}
|
||||
|
||||
fn with_optional_trait_ref<T>(&mut self, id: NodeId,
|
||||
opt_trait_ref: &Option<TraitRef>,
|
||||
f: |&mut Resolver| -> T) -> T {
|
||||
fn with_optional_trait_ref<T, F>(&mut self, id: NodeId,
|
||||
opt_trait_ref: &Option<TraitRef>,
|
||||
f: F) -> T where
|
||||
F: FnOnce(&mut Resolver) -> T,
|
||||
{
|
||||
let new_val = match *opt_trait_ref {
|
||||
Some(ref trait_ref) => {
|
||||
self.resolve_trait_reference(id, trait_ref, TraitImplementation);
|
||||
@ -5620,7 +5632,9 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn with_no_errors<T>(&mut self, f: |&mut Resolver| -> T) -> T {
|
||||
fn with_no_errors<T, F>(&mut self, f: F) -> T where
|
||||
F: FnOnce(&mut Resolver) -> T,
|
||||
{
|
||||
self.emit_errors = false;
|
||||
let rs = f(self);
|
||||
self.emit_errors = true;
|
||||
|
@ -247,7 +247,9 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
||||
}
|
||||
|
||||
impl<'a> LifetimeContext<'a> {
|
||||
fn with(&mut self, wrap_scope: ScopeChain, f: |&mut LifetimeContext|) {
|
||||
fn with<F>(&mut self, wrap_scope: ScopeChain, f: F) where
|
||||
F: FnOnce(&mut LifetimeContext),
|
||||
{
|
||||
let LifetimeContext {sess, ref mut named_region_map, ..} = *self;
|
||||
let mut this = LifetimeContext {
|
||||
sess: sess,
|
||||
@ -278,10 +280,12 @@ impl<'a> LifetimeContext<'a> {
|
||||
/// already in scope (for a fn item, that will be 0, but for a method it might not be). Late
|
||||
/// bound lifetimes are resolved by name and associated with a binder id (`binder_id`), so the
|
||||
/// ordering is not important there.
|
||||
fn visit_early_late(&mut self,
|
||||
early_space: subst::ParamSpace,
|
||||
generics: &ast::Generics,
|
||||
walk: |&mut LifetimeContext|) {
|
||||
fn visit_early_late<F>(&mut self,
|
||||
early_space: subst::ParamSpace,
|
||||
generics: &ast::Generics,
|
||||
walk: F) where
|
||||
F: FnOnce(&mut LifetimeContext),
|
||||
{
|
||||
let referenced_idents = early_bound_lifetime_names(generics);
|
||||
|
||||
debug!("visit_early_late: referenced_idents={}",
|
||||
@ -290,8 +294,8 @@ impl<'a> LifetimeContext<'a> {
|
||||
let (early, late) = generics.lifetimes.clone().partition(
|
||||
|l| referenced_idents.iter().any(|&i| i == l.lifetime.name));
|
||||
|
||||
self.with(EarlyScope(early_space, &early, self.scope), |this| {
|
||||
this.with(LateScope(&late, this.scope), |this| {
|
||||
self.with(EarlyScope(early_space, &early, self.scope), move |this| {
|
||||
this.with(LateScope(&late, this.scope), move |this| {
|
||||
this.check_lifetime_defs(&generics.lifetimes);
|
||||
walk(this);
|
||||
});
|
||||
|
@ -43,7 +43,9 @@ struct Annotator {
|
||||
impl Annotator {
|
||||
// Determine the stability for a node based on its attributes and inherited
|
||||
// stability. The stability is recorded in the index and used as the parent.
|
||||
fn annotate(&mut self, id: NodeId, attrs: &Vec<Attribute>, f: |&mut Annotator|) {
|
||||
fn annotate<F>(&mut self, id: NodeId, attrs: &Vec<Attribute>, f: F) where
|
||||
F: FnOnce(&mut Annotator),
|
||||
{
|
||||
match attr::find_stability(attrs.as_slice()) {
|
||||
Some(stab) => {
|
||||
self.index.local.insert(id, stab.clone());
|
||||
|
@ -167,10 +167,9 @@ impl<'tcx> Substs<'tcx> {
|
||||
}
|
||||
|
||||
impl RegionSubsts {
|
||||
fn map<A>(self,
|
||||
a: A,
|
||||
op: |VecPerParamSpace<ty::Region>, A| -> VecPerParamSpace<ty::Region>)
|
||||
-> RegionSubsts {
|
||||
fn map<A, F>(self, a: A, op: F) -> RegionSubsts where
|
||||
F: FnOnce(VecPerParamSpace<ty::Region>, A) -> VecPerParamSpace<ty::Region>,
|
||||
{
|
||||
match self {
|
||||
ErasedRegions => ErasedRegions,
|
||||
NonerasedRegions(r) => NonerasedRegions(op(r, a))
|
||||
@ -415,7 +414,9 @@ impl<T> VecPerParamSpace<T> {
|
||||
self.content.as_slice()
|
||||
}
|
||||
|
||||
pub fn all_vecs(&self, pred: |&[T]| -> bool) -> bool {
|
||||
pub fn all_vecs<P>(&self, mut pred: P) -> bool where
|
||||
P: FnMut(&[T]) -> bool,
|
||||
{
|
||||
let spaces = [TypeSpace, SelfSpace, FnSpace];
|
||||
spaces.iter().all(|&space| { pred(self.get_slice(space)) })
|
||||
}
|
||||
@ -450,7 +451,9 @@ impl<T> VecPerParamSpace<T> {
|
||||
self.assoc_limit)
|
||||
}
|
||||
|
||||
pub fn map_move<U>(self, pred: |T| -> U) -> VecPerParamSpace<U> {
|
||||
pub fn map_move<U, F>(self, mut pred: F) -> VecPerParamSpace<U> where
|
||||
F: FnMut(T) -> U,
|
||||
{
|
||||
let SeparateVecsPerParamSpace {
|
||||
types: t,
|
||||
selfs: s,
|
||||
|
@ -322,7 +322,9 @@ impl<'tcx, N> Vtable<'tcx, N> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_move_nested<M>(self, op: |N| -> M) -> Vtable<'tcx, M> {
|
||||
pub fn map_move_nested<M, F>(self, op: F) -> Vtable<'tcx, M> where
|
||||
F: FnMut(N) -> M,
|
||||
{
|
||||
match self {
|
||||
VtableImpl(i) => VtableImpl(i.map_move_nested(op)),
|
||||
VtableFnPointer(sig) => VtableFnPointer(sig),
|
||||
@ -348,8 +350,9 @@ impl<'tcx, N> VtableImplData<'tcx, N> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_move_nested<M>(self, op: |N| -> M)
|
||||
-> VtableImplData<'tcx, M> {
|
||||
pub fn map_move_nested<M, F>(self, op: F) -> VtableImplData<'tcx, M> where
|
||||
F: FnMut(N) -> M,
|
||||
{
|
||||
let VtableImplData { impl_def_id, substs, nested } = self;
|
||||
VtableImplData {
|
||||
impl_def_id: impl_def_id,
|
||||
@ -370,7 +373,9 @@ impl<N> VtableBuiltinData<N> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_move_nested<M>(self, op: |N| -> M) -> VtableBuiltinData<M> {
|
||||
pub fn map_move_nested<M, F>(self, op: F) -> VtableBuiltinData<M> where
|
||||
F: FnMut(N) -> M,
|
||||
{
|
||||
VtableBuiltinData {
|
||||
nested: self.nested.map_move(op)
|
||||
}
|
||||
|
@ -306,10 +306,11 @@ pub fn predicate_for_builtin_bound<'tcx>(
|
||||
/// of caller obligations), search through the trait and supertraits to find one where `test(d)` is
|
||||
/// true, where `d` is the def-id of the trait/supertrait. If any is found, return `Some(p)` where
|
||||
/// `p` is the path to that trait/supertrait. Else `None`.
|
||||
pub fn search_trait_and_supertraits_from_bound<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
caller_bound: Rc<ty::TraitRef<'tcx>>,
|
||||
test: |ast::DefId| -> bool)
|
||||
-> Option<VtableParamData<'tcx>>
|
||||
pub fn search_trait_and_supertraits_from_bound<'tcx, F>(tcx: &ty::ctxt<'tcx>,
|
||||
caller_bound: Rc<ty::TraitRef<'tcx>>,
|
||||
mut test: F)
|
||||
-> Option<VtableParamData<'tcx>> where
|
||||
F: FnMut(ast::DefId) -> bool,
|
||||
{
|
||||
for bound in transitive_bounds(tcx, &[caller_bound]) {
|
||||
if test(bound.def_id) {
|
||||
|
@ -2420,10 +2420,13 @@ pub fn mk_param_from_def<'tcx>(cx: &ctxt<'tcx>, def: &TypeParameterDef) -> Ty<'t
|
||||
|
||||
pub fn mk_open<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { mk_t(cx, ty_open(ty)) }
|
||||
|
||||
pub fn walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>|) {
|
||||
pub fn walk_ty<'tcx, F>(ty: Ty<'tcx>, mut f: F) where
|
||||
F: FnMut(Ty<'tcx>),
|
||||
{
|
||||
maybe_walk_ty(ty, |ty| { f(ty); true });
|
||||
}
|
||||
|
||||
// FIXME(#19596) unbox `f`
|
||||
pub fn maybe_walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>| -> bool) {
|
||||
if !f(ty) {
|
||||
return;
|
||||
@ -2464,9 +2467,11 @@ pub fn maybe_walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>| -> bool) {
|
||||
}
|
||||
|
||||
// Folds types from the bottom up.
|
||||
pub fn fold_ty<'tcx>(cx: &ctxt<'tcx>, t0: Ty<'tcx>,
|
||||
fldop: |Ty<'tcx>| -> Ty<'tcx>)
|
||||
-> Ty<'tcx> {
|
||||
pub fn fold_ty<'tcx, F>(cx: &ctxt<'tcx>, t0: Ty<'tcx>,
|
||||
fldop: F)
|
||||
-> Ty<'tcx> where
|
||||
F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
|
||||
{
|
||||
let mut f = ty_fold::BottomUpFolder {tcx: cx, fldop: fldop};
|
||||
f.fold_ty(t0)
|
||||
}
|
||||
@ -2843,7 +2848,9 @@ impl TypeContents {
|
||||
*self & TC::ReachesAll
|
||||
}
|
||||
|
||||
pub fn union<T>(v: &[T], f: |&T| -> TypeContents) -> TypeContents {
|
||||
pub fn union<T, F>(v: &[T], mut f: F) -> TypeContents where
|
||||
F: FnMut(&T) -> TypeContents,
|
||||
{
|
||||
v.iter().fold(TC::None, |tc, ty| tc | f(ty))
|
||||
}
|
||||
|
||||
@ -3162,10 +3169,12 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
|
||||
|
||||
// Iterates over all builtin bounds on the type parameter def, including
|
||||
// those inherited from traits with builtin-kind-supertraits.
|
||||
fn each_inherited_builtin_bound<'tcx>(cx: &ctxt<'tcx>,
|
||||
bounds: BuiltinBounds,
|
||||
traits: &[Rc<TraitRef<'tcx>>],
|
||||
f: |BuiltinBound|) {
|
||||
fn each_inherited_builtin_bound<'tcx, F>(cx: &ctxt<'tcx>,
|
||||
bounds: BuiltinBounds,
|
||||
traits: &[Rc<TraitRef<'tcx>>],
|
||||
mut f: F) where
|
||||
F: FnMut(BuiltinBound),
|
||||
{
|
||||
for bound in bounds.iter() {
|
||||
f(bound);
|
||||
}
|
||||
@ -3959,14 +3968,15 @@ pub fn local_var_name_str(cx: &ctxt, id: NodeId) -> InternedString {
|
||||
}
|
||||
|
||||
/// See `expr_ty_adjusted`
|
||||
pub fn adjust_ty<'tcx>(cx: &ctxt<'tcx>,
|
||||
span: Span,
|
||||
expr_id: ast::NodeId,
|
||||
unadjusted_ty: Ty<'tcx>,
|
||||
adjustment: Option<&AutoAdjustment<'tcx>>,
|
||||
method_type: |MethodCall| -> Option<Ty<'tcx>>)
|
||||
-> Ty<'tcx> {
|
||||
|
||||
pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>,
|
||||
span: Span,
|
||||
expr_id: ast::NodeId,
|
||||
unadjusted_ty: Ty<'tcx>,
|
||||
adjustment: Option<&AutoAdjustment<'tcx>>,
|
||||
mut method_type: F)
|
||||
-> Ty<'tcx> where
|
||||
F: FnMut(MethodCall) -> Option<Ty<'tcx>>,
|
||||
{
|
||||
if let ty_err = unadjusted_ty.sty {
|
||||
return unadjusted_ty;
|
||||
}
|
||||
@ -4604,11 +4614,13 @@ pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
|
||||
/// id is local, it should have been loaded into the map by the `typeck::collect` phase. If the
|
||||
/// def-id is external, then we have to go consult the crate loading code (and cache the result for
|
||||
/// the future).
|
||||
fn lookup_locally_or_in_crate_store<V:Clone>(
|
||||
descr: &str,
|
||||
def_id: ast::DefId,
|
||||
map: &mut DefIdMap<V>,
|
||||
load_external: || -> V) -> V {
|
||||
fn lookup_locally_or_in_crate_store<V, F>(descr: &str,
|
||||
def_id: ast::DefId,
|
||||
map: &mut DefIdMap<V>,
|
||||
load_external: F) -> V where
|
||||
V: Clone,
|
||||
F: FnOnce() -> V,
|
||||
{
|
||||
match map.get(&def_id).cloned() {
|
||||
Some(v) => { return v; }
|
||||
None => { }
|
||||
@ -5164,7 +5176,9 @@ pub fn predicates<'tcx>(
|
||||
/// Iterate over attributes of a definition.
|
||||
// (This should really be an iterator, but that would require csearch and
|
||||
// decoder to use iterators instead of higher-order functions.)
|
||||
pub fn each_attr(tcx: &ctxt, did: DefId, f: |&ast::Attribute| -> bool) -> bool {
|
||||
pub fn each_attr<F>(tcx: &ctxt, did: DefId, mut f: F) -> bool where
|
||||
F: FnMut(&ast::Attribute) -> bool,
|
||||
{
|
||||
if is_local(did) {
|
||||
let item = tcx.map.expect_item(did.node);
|
||||
item.attrs.iter().all(|attr| f(attr))
|
||||
@ -5503,10 +5517,11 @@ pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> uint {
|
||||
// Here, the supertraits are the transitive closure of the supertrait
|
||||
// relation on the supertraits from each bounded trait's constraint
|
||||
// list.
|
||||
pub fn each_bound_trait_and_supertraits<'tcx>(tcx: &ctxt<'tcx>,
|
||||
bounds: &[Rc<TraitRef<'tcx>>],
|
||||
f: |Rc<TraitRef<'tcx>>| -> bool)
|
||||
-> bool
|
||||
pub fn each_bound_trait_and_supertraits<'tcx, F>(tcx: &ctxt<'tcx>,
|
||||
bounds: &[Rc<TraitRef<'tcx>>],
|
||||
mut f: F)
|
||||
-> bool where
|
||||
F: FnMut(Rc<TraitRef<'tcx>>) -> bool,
|
||||
{
|
||||
for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
|
||||
if !f(bound_trait_ref) {
|
||||
@ -6194,7 +6209,9 @@ pub type FreevarMap = NodeMap<Vec<Freevar>>;
|
||||
|
||||
pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
|
||||
|
||||
pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[Freevar]| -> T) -> T {
|
||||
pub fn with_freevars<T, F>(tcx: &ty::ctxt, fid: ast::NodeId, f: F) -> T where
|
||||
F: FnOnce(&[Freevar]) -> T,
|
||||
{
|
||||
match tcx.freevars.borrow().get(&fid) {
|
||||
None => f(&[]),
|
||||
Some(d) => f(d.as_slice())
|
||||
@ -6242,12 +6259,13 @@ pub fn erase_late_bound_regions<'tcx, HR>(
|
||||
}
|
||||
|
||||
/// Replaces the late-bound-regions in `value` that are bound by `value`.
|
||||
pub fn replace_late_bound_regions<'tcx, HR>(
|
||||
pub fn replace_late_bound_regions<'tcx, HR, F>(
|
||||
tcx: &ty::ctxt<'tcx>,
|
||||
value: &HR,
|
||||
mapf: |BoundRegion, DebruijnIndex| -> ty::Region)
|
||||
-> (HR, FnvHashMap<ty::BoundRegion,ty::Region>)
|
||||
where HR : HigherRankedFoldable<'tcx>
|
||||
mut mapf: F)
|
||||
-> (HR, FnvHashMap<ty::BoundRegion, ty::Region>) where
|
||||
HR : HigherRankedFoldable<'tcx>,
|
||||
F: FnMut(BoundRegion, DebruijnIndex) -> ty::Region,
|
||||
{
|
||||
debug!("replace_late_bound_regions({})", value.repr(tcx));
|
||||
|
||||
|
@ -743,12 +743,14 @@ impl<'tcx, T:HigherRankedFoldable<'tcx>> HigherRankedFoldable<'tcx> for Rc<T> {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Some sample folders
|
||||
|
||||
pub struct BottomUpFolder<'a, 'tcx: 'a> {
|
||||
pub struct BottomUpFolder<'a, 'tcx: 'a, F> where F: FnMut(Ty<'tcx>) -> Ty<'tcx> {
|
||||
pub tcx: &'a ty::ctxt<'tcx>,
|
||||
pub fldop: |Ty<'tcx>|: 'a -> Ty<'tcx>,
|
||||
pub fldop: F,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx> {
|
||||
impl<'a, 'tcx, F> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx, F> where
|
||||
F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
|
||||
{
|
||||
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { self.tcx }
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
@ -772,15 +774,14 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx> {
|
||||
/// (The distinction between "free" and "bound" is represented by
|
||||
/// keeping track of each `FnSig` in the lexical context of the
|
||||
/// current position of the fold.)
|
||||
pub struct RegionFolder<'a, 'tcx: 'a> {
|
||||
pub struct RegionFolder<'a, 'tcx: 'a, F> where F: FnMut(ty::Region, uint) -> ty::Region {
|
||||
tcx: &'a ty::ctxt<'tcx>,
|
||||
current_depth: uint,
|
||||
fld_r: |ty::Region, uint|: 'a -> ty::Region,
|
||||
fld_r: F,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> RegionFolder<'a, 'tcx> {
|
||||
pub fn new(tcx: &'a ty::ctxt<'tcx>, fld_r: |ty::Region, uint|: 'a -> ty::Region)
|
||||
-> RegionFolder<'a, 'tcx> {
|
||||
impl<'a, 'tcx, F> RegionFolder<'a, 'tcx, F> where F: FnMut(ty::Region, uint) -> ty::Region {
|
||||
pub fn new(tcx: &'a ty::ctxt<'tcx>, fld_r: F) -> RegionFolder<'a, 'tcx, F> {
|
||||
RegionFolder {
|
||||
tcx: tcx,
|
||||
current_depth: 1,
|
||||
@ -789,7 +790,9 @@ impl<'a, 'tcx> RegionFolder<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
||||
impl<'a, 'tcx, F> TypeFolder<'tcx> for RegionFolder<'a, 'tcx, F> where
|
||||
F: FnMut(ty::Region, uint) -> ty::Region,
|
||||
{
|
||||
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { self.tcx }
|
||||
|
||||
fn enter_region_binder(&mut self) {
|
||||
|
@ -27,7 +27,9 @@ pub struct ErrorReported;
|
||||
|
||||
impl Copy for ErrorReported {}
|
||||
|
||||
pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
|
||||
pub fn time<T, U, F>(do_it: bool, what: &str, u: U, f: F) -> T where
|
||||
F: FnOnce(U) -> T,
|
||||
{
|
||||
thread_local!(static DEPTH: Cell<uint> = Cell::new(0));
|
||||
if !do_it { return f(u); }
|
||||
|
||||
@ -39,9 +41,13 @@ pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
|
||||
|
||||
let mut u = Some(u);
|
||||
let mut rv = None;
|
||||
let dur = Duration::span(|| {
|
||||
rv = Some(f(u.take().unwrap()))
|
||||
});
|
||||
let dur = {
|
||||
let ref mut rvp = rv;
|
||||
|
||||
Duration::span(move || {
|
||||
*rvp = Some(f(u.take().unwrap()))
|
||||
})
|
||||
};
|
||||
let rv = rv.unwrap();
|
||||
|
||||
println!("{}time: {}.{:03} \t{}", " ".repeat(old),
|
||||
@ -51,7 +57,10 @@ pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
|
||||
rv
|
||||
}
|
||||
|
||||
pub fn indent<R: Show>(op: || -> R) -> R {
|
||||
pub fn indent<R, F>(op: F) -> R where
|
||||
R: Show,
|
||||
F: FnOnce() -> R,
|
||||
{
|
||||
// Use in conjunction with the log post-processor like `src/etc/indenter`
|
||||
// to make debug output more readable.
|
||||
debug!(">>");
|
||||
@ -73,12 +82,12 @@ pub fn indenter() -> Indenter {
|
||||
Indenter { _cannot_construct_outside_of_this_module: () }
|
||||
}
|
||||
|
||||
struct LoopQueryVisitor<'a> {
|
||||
p: |&ast::Expr_|: 'a -> bool,
|
||||
struct LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
|
||||
p: P,
|
||||
flag: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'v> Visitor<'v> for LoopQueryVisitor<'a> {
|
||||
impl<'v, P> Visitor<'v> for LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
|
||||
fn visit_expr(&mut self, e: &ast::Expr) {
|
||||
self.flag |= (self.p)(&e.node);
|
||||
match e.node {
|
||||
@ -92,7 +101,7 @@ impl<'a, 'v> Visitor<'v> for LoopQueryVisitor<'a> {
|
||||
|
||||
// Takes a predicate p, returns true iff p is true for any subexpressions
|
||||
// of b -- skipping any inner loops (loop, while, loop_body)
|
||||
pub fn loop_query(b: &ast::Block, p: |&ast::Expr_| -> bool) -> bool {
|
||||
pub fn loop_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr_) -> bool {
|
||||
let mut v = LoopQueryVisitor {
|
||||
p: p,
|
||||
flag: false,
|
||||
@ -101,12 +110,12 @@ pub fn loop_query(b: &ast::Block, p: |&ast::Expr_| -> bool) -> bool {
|
||||
return v.flag;
|
||||
}
|
||||
|
||||
struct BlockQueryVisitor<'a> {
|
||||
p: |&ast::Expr|: 'a -> bool,
|
||||
struct BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
|
||||
p: P,
|
||||
flag: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'v> Visitor<'v> for BlockQueryVisitor<'a> {
|
||||
impl<'v, P> Visitor<'v> for BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
|
||||
fn visit_expr(&mut self, e: &ast::Expr) {
|
||||
self.flag |= (self.p)(e);
|
||||
visit::walk_expr(self, e)
|
||||
@ -115,7 +124,7 @@ impl<'a, 'v> Visitor<'v> for BlockQueryVisitor<'a> {
|
||||
|
||||
// Takes a predicate p, returns true iff p is true for any subexpressions
|
||||
// of b -- skipping any inner loops (loop, while, loop_body)
|
||||
pub fn block_query(b: &ast::Block, p: |&ast::Expr| -> bool) -> bool {
|
||||
pub fn block_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr) -> bool {
|
||||
let mut v = BlockQueryVisitor {
|
||||
p: p,
|
||||
flag: false,
|
||||
@ -194,11 +203,12 @@ pub fn can_reach<S,H:Hasher<S>,T:Eq+Clone+Hash<S>>(
|
||||
/// }
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn memoized<T: Clone + Hash<S> + Eq, U: Clone, S, H: Hasher<S>>(
|
||||
cache: &RefCell<HashMap<T, U, H>>,
|
||||
arg: T,
|
||||
f: |T| -> U
|
||||
) -> U {
|
||||
pub fn memoized<T, U, S, H, F>(cache: &RefCell<HashMap<T, U, H>>, arg: T, f: F) -> U where
|
||||
T: Clone + Hash<S> + Eq,
|
||||
U: Clone,
|
||||
H: Hasher<S>,
|
||||
F: FnOnce(T) -> U,
|
||||
{
|
||||
let key = arg.clone();
|
||||
let result = cache.borrow().get(&key).map(|result| result.clone());
|
||||
match result {
|
||||
|
@ -232,8 +232,9 @@ fn compatible_borrow_kinds(borrow_kind1: ty::BorrowKind,
|
||||
impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
pub fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.bccx.tcx }
|
||||
|
||||
pub fn each_issued_loan(&self, scope: region::CodeExtent, op: |&Loan<'tcx>| -> bool)
|
||||
-> bool {
|
||||
pub fn each_issued_loan<F>(&self, scope: region::CodeExtent, mut op: F) -> bool where
|
||||
F: FnMut(&Loan<'tcx>) -> bool,
|
||||
{
|
||||
//! Iterates over each loan that has been issued
|
||||
//! on entrance to `scope`, regardless of whether it is
|
||||
//! actually *in scope* at that point. Sometimes loans
|
||||
@ -246,10 +247,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn each_in_scope_loan(&self,
|
||||
scope: region::CodeExtent,
|
||||
op: |&Loan<'tcx>| -> bool)
|
||||
-> bool {
|
||||
pub fn each_in_scope_loan<F>(&self, scope: region::CodeExtent, mut op: F) -> bool where
|
||||
F: FnMut(&Loan<'tcx>) -> bool,
|
||||
{
|
||||
//! Like `each_issued_loan()`, but only considers loans that are
|
||||
//! currently in scope.
|
||||
|
||||
@ -263,11 +263,13 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
fn each_in_scope_loan_affecting_path(&self,
|
||||
scope: region::CodeExtent,
|
||||
loan_path: &LoanPath<'tcx>,
|
||||
op: |&Loan<'tcx>| -> bool)
|
||||
-> bool {
|
||||
fn each_in_scope_loan_affecting_path<F>(&self,
|
||||
scope: region::CodeExtent,
|
||||
loan_path: &LoanPath<'tcx>,
|
||||
mut op: F)
|
||||
-> bool where
|
||||
F: FnMut(&Loan<'tcx>) -> bool,
|
||||
{
|
||||
//! Iterates through all of the in-scope loans affecting `loan_path`,
|
||||
//! calling `op`, and ceasing iteration if `false` is returned.
|
||||
|
||||
|
@ -523,8 +523,9 @@ impl<'tcx> MoveData<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn each_base_path(&self, index: MovePathIndex, f: |MovePathIndex| -> bool)
|
||||
-> bool {
|
||||
fn each_base_path<F>(&self, index: MovePathIndex, mut f: F) -> bool where
|
||||
F: FnMut(MovePathIndex) -> bool,
|
||||
{
|
||||
let mut p = index;
|
||||
while p != InvalidMovePathIndex {
|
||||
if !f(p) {
|
||||
@ -535,10 +536,8 @@ impl<'tcx> MoveData<'tcx> {
|
||||
return true;
|
||||
}
|
||||
|
||||
fn each_extending_path(&self,
|
||||
index: MovePathIndex,
|
||||
f: |MovePathIndex| -> bool)
|
||||
-> bool {
|
||||
// FIXME(#19596) unbox `f`
|
||||
fn each_extending_path(&self, index: MovePathIndex, f: |MovePathIndex| -> bool) -> bool {
|
||||
if !f(index) {
|
||||
return false;
|
||||
}
|
||||
@ -554,10 +553,9 @@ impl<'tcx> MoveData<'tcx> {
|
||||
return true;
|
||||
}
|
||||
|
||||
fn each_applicable_move(&self,
|
||||
index0: MovePathIndex,
|
||||
f: |MoveIndex| -> bool)
|
||||
-> bool {
|
||||
fn each_applicable_move<F>(&self, index0: MovePathIndex, mut f: F) -> bool where
|
||||
F: FnMut(MoveIndex) -> bool,
|
||||
{
|
||||
let mut ret = true;
|
||||
self.each_extending_path(index0, |index| {
|
||||
let mut p = self.path_first_move(index);
|
||||
@ -660,11 +658,13 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
|
||||
/// Iterates through each move of `loan_path` (or some base path of `loan_path`) that *may*
|
||||
/// have occurred on entry to `id` without an intervening assignment. In other words, any moves
|
||||
/// that would invalidate a reference to `loan_path` at location `id`.
|
||||
pub fn each_move_of(&self,
|
||||
id: ast::NodeId,
|
||||
loan_path: &Rc<LoanPath<'tcx>>,
|
||||
f: |&Move, &LoanPath<'tcx>| -> bool)
|
||||
-> bool {
|
||||
pub fn each_move_of<F>(&self,
|
||||
id: ast::NodeId,
|
||||
loan_path: &Rc<LoanPath<'tcx>>,
|
||||
mut f: F)
|
||||
-> bool where
|
||||
F: FnMut(&Move, &LoanPath<'tcx>) -> bool,
|
||||
{
|
||||
// Bad scenarios:
|
||||
//
|
||||
// 1. Move of `a.b.c`, use of `a.b.c`
|
||||
@ -715,11 +715,13 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
|
||||
|
||||
/// Iterates through every assignment to `loan_path` that may have occurred on entry to `id`.
|
||||
/// `loan_path` must be a single variable.
|
||||
pub fn each_assignment_of(&self,
|
||||
id: ast::NodeId,
|
||||
loan_path: &Rc<LoanPath<'tcx>>,
|
||||
f: |&Assignment| -> bool)
|
||||
-> bool {
|
||||
pub fn each_assignment_of<F>(&self,
|
||||
id: ast::NodeId,
|
||||
loan_path: &Rc<LoanPath<'tcx>>,
|
||||
mut f: F)
|
||||
-> bool where
|
||||
F: FnMut(&Assignment) -> bool,
|
||||
{
|
||||
let loan_path_index = {
|
||||
match self.move_data.existing_move_path(loan_path) {
|
||||
Some(i) => i,
|
||||
|
@ -75,11 +75,13 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn build_set<O:DataFlowOperator>(&self,
|
||||
e: EntryOrExit,
|
||||
cfgidx: CFGIndex,
|
||||
dfcx: &DataFlowContext<'a, 'tcx, O>,
|
||||
to_lp: |uint| -> Rc<LoanPath<'tcx>>) -> String {
|
||||
fn build_set<O:DataFlowOperator, F>(&self,
|
||||
e: EntryOrExit,
|
||||
cfgidx: CFGIndex,
|
||||
dfcx: &DataFlowContext<'a, 'tcx, O>,
|
||||
mut to_lp: F) -> String where
|
||||
F: FnMut(uint) -> Rc<LoanPath<'tcx>>,
|
||||
{
|
||||
let mut saw_some = false;
|
||||
let mut set = "{".to_string();
|
||||
dfcx.each_bit_for_node(e, cfgidx, |index| {
|
||||
@ -98,7 +100,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
|
||||
|
||||
fn dataflow_loans_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
|
||||
let dfcx = &self.analysis_data.loans;
|
||||
let loan_index_to_path = |loan_index| {
|
||||
let loan_index_to_path = |&mut: loan_index| {
|
||||
let all_loans = &self.analysis_data.all_loans;
|
||||
all_loans[loan_index].loan_path()
|
||||
};
|
||||
@ -107,7 +109,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
|
||||
|
||||
fn dataflow_moves_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
|
||||
let dfcx = &self.analysis_data.move_data.dfcx_moves;
|
||||
let move_index_to_path = |move_index| {
|
||||
let move_index_to_path = |&mut: move_index| {
|
||||
let move_data = &self.analysis_data.move_data.move_data;
|
||||
let moves = move_data.moves.borrow();
|
||||
let the_move = &(*moves)[move_index];
|
||||
@ -118,7 +120,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
|
||||
|
||||
fn dataflow_assigns_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
|
||||
let dfcx = &self.analysis_data.move_data.dfcx_assign;
|
||||
let assign_index_to_path = |assign_index| {
|
||||
let assign_index_to_path = |&mut: assign_index| {
|
||||
let move_data = &self.analysis_data.move_data.move_data;
|
||||
let assignments = move_data.var_assignments.borrow();
|
||||
let assignment = &(*assignments)[assign_index];
|
||||
|
Loading…
x
Reference in New Issue
Block a user