Skip to content

Commit 40ed626

Browse files
committed
fix 'boxed iterator can't be used in for loop' problem.
Had to hack around this for now with an iterator adaptor
1 parent cf865df commit 40ed626

File tree

3 files changed

+42
-12
lines changed

3 files changed

+42
-12
lines changed

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ extern crate syntax;
77
extern crate time;
88
extern crate debug;
99
extern crate collections;
10+
extern crate core;
1011

1112
#[cfg(not(test))]
1213
use racer::Match;

src/racer/mod.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::io::File;
22
use std::io::BufferedReader;
3-
use std::str;
3+
use std::{str,vec};
44

55
pub mod scopes;
66
pub mod ast;
@@ -60,7 +60,7 @@ pub fn load_file_and_mask_comments(filepath: &Path) -> String {
6060
return msrc;
6161
}
6262

63-
pub fn complete_from_file(src: &str, filepath: &Path, pos: uint) -> Box<Iterator<Match>> {
63+
pub fn complete_from_file(src: &str, filepath: &Path, pos: uint) -> vec::MoveItems<Match> {
6464

6565
let start = scopes::get_start_of_search_expr(src, pos);
6666
let expr = src.slice(start,pos);
@@ -69,24 +69,26 @@ pub fn complete_from_file(src: &str, filepath: &Path, pos: uint) -> Box<Iterator
6969

7070
debug!("PHIL contextstr is |{}|, searchstr is |{}|",contextstr, searchstr);
7171

72+
let mut out = Vec::new();
7273

7374
match completetype {
7475
Path => {
7576
let v : Vec<&str> = expr.split_str("::").collect();
76-
return nameres::resolve_path(v.as_slice(), filepath, pos,
77-
StartsWith, BothNamespaces);
77+
for m in nameres::resolve_path(v.as_slice(), filepath, pos,
78+
StartsWith, BothNamespaces) {
79+
out.push(m);
80+
}
7881
},
7982
Field => {
80-
let mut out = Vec::new();
8183
let context = ast::get_type_of(contextstr.to_string(), filepath, pos);
8284
context.map(|m| {
8385
for m in nameres::search_for_field(m, searchstr, StartsWith) {
8486
out.push(m)
8587
}
8688
});
87-
return box out.move_iter() as Box<Iterator<Match>>
8889
}
8990
}
91+
return out.move_iter();
9092
}
9193

9294
pub fn find_definition(src: &str, filepath: &Path, pos: uint) -> Option<Match> {

src/racer/nameres.rs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -535,8 +535,23 @@ pub fn do_local_search_with_string(path: &[&str], filepath: &Path, pos: uint,
535535
return out.move_iter();
536536
}
537537

538+
539+
// HACK: Make box iterator support iterator trait
540+
//
541+
// I can't get the type signature to resolve_name to compile, so instead am boxing it into a trait object and then returning it as an iterator
542+
pub struct BoxIter {
543+
iter: Box<Iterator<Match>>
544+
}
545+
546+
impl Iterator<Match> for BoxIter {
547+
#[inline]
548+
fn next(&mut self) -> Option<Match> {
549+
return self.iter.next();
550+
}
551+
}
552+
538553
pub fn resolve_name(searchstr: &str, filepath: &Path, pos: uint,
539-
search_type: SearchType, namespace: Namespace) -> Box<Iterator<Match>> {
554+
search_type: SearchType, namespace: Namespace) -> BoxIter {
540555
let msrc = racer::load_file_and_mask_comments(filepath);
541556

542557
let s = String::from_str(searchstr);
@@ -604,21 +619,32 @@ pub fn resolve_name(searchstr: &str, filepath: &Path, pos: uint,
604619
None
605620
}.move_iter().flat_map(|p| p()));
606621

607-
return box it as Box<Iterator<Match>>;
622+
//return it;
623+
624+
let it = box it as Box<Iterator<Match>>;
625+
return BoxIter{ iter: it };
626+
608627
}
609628

610629

611630
pub fn resolve_path(path: &[&str], filepath: &Path, pos: uint,
612-
search_type: SearchType, namespace: Namespace) -> Box<Iterator<Match>> {
631+
search_type: SearchType, namespace: Namespace) -> vec::MoveItems<Match> {
613632
debug!("PHIL do_local_search path {} in {}",path, filepath.as_str());
614633

634+
let mut out = Vec::new();
635+
615636
if path.len() == 1 {
616637
let searchstr = path[0];
617-
return resolve_name(searchstr, filepath, pos, search_type, namespace);
638+
for m in resolve_name(searchstr, filepath, pos, search_type, namespace) {
639+
out.push(m);
640+
}
641+
return out.move_iter();
618642
} else {
619643
if path[0] == "" {
620644
// match global searches starting with :: - e.g. ::std::blah::...
621-
return box do_external_search(path.slice_from(1), filepath, pos, search_type, namespace) as Box<Iterator<Match>>;
645+
for m in do_external_search(path.slice_from(1), filepath, pos, search_type, namespace) {
646+
out.push(m);
647+
}
622648
}
623649

624650
let parent_path = path.slice_to(path.len()-1);
@@ -661,7 +687,8 @@ pub fn resolve_path(path: &[&str], filepath: &Path, pos: uint,
661687
_ => ()
662688
}
663689
});
664-
return box out.move_iter() as Box<Iterator<Match>>;
690+
691+
return out.move_iter();
665692
}
666693
}
667694

0 commit comments

Comments
 (0)