/// When name resolution fails, this method can be used to look up candidate
/// entities with the expected name. It allows filtering them using the
/// supplied predicate (which should be used to only accept the types of
/// definitions expected e.g. traits). The lookup spans across all crates.
///
/// NOTE: The method does not look into imports, but this is not a problem,
/// since we report the definitions (thus, the de-aliased imports).
When name resolution fails, this method can be used to look up candidate
entities with the expected name. It allows filtering them using the
supplied predicate (which should be used to only accept the types of
definitions expected e.g. traits). The lookup spans across all crates.

The method does not look into imports, but this is not a problem,
since we report the definitions (thus, the de-aliased imports).
When name resolution fails this method can be used to look up candidate entities with the expected name . It allows filtering them using the supplied predicate ( which should be used to only accept the types of definitions expected e . g . traits ) . The lookup spans across all crates . The method does not look into imports but this is not a problem since we report the definitions ( thus the de - aliased imports ) .
fn lookup_candidates<FilterFn>(&mut self,
                                   lookup_name: Name,
                                   namespace: Namespace,
                                   filter_fn: FilterFn) -> SuggestedCandidates
        where FilterFn: Fn(Def) -> bool {
        let mut lookup_results = Vec::new();
        let mut worklist = Vec::new();
        worklist.push((self.graph_root, Vec::new(), false));
        while let Some((in_module,
                        path_segments,
                        in_module_is_extern)) = worklist.pop() {
            self.populate_module_if_necessary(in_module);
            in_module.for_each_child(|name, ns, name_binding| {
                // avoid imports entirely
                if name_binding.is_import() { return; }
                // collect results based on the filter function
                if let Some(def) = name_binding.def() {
                    if name == lookup_name && ns == namespace && filter_fn(def) {
                        // create the path
                        let ident = ast::Ident::with_empty_ctxt(name);
                        let params = PathParameters::none();
                        let segment = PathSegment {
                            identifier: ident,
                            parameters: params,
                        };
                        let span = name_binding.span;
                        let mut segms = path_segments.clone();
                        segms.push(segment);
                        let path = Path {
                            span: span,
                            global: true,
                            segments: segms,
                        };
                        // the entity is accessible in the following cases:
                        // 1. if it's defined in the same crate, it's always
                        // accessible (since private entities can be made public)
                        // 2. if it's defined in another crate, it's accessible
                        // only if both the module is public and the entity is
                        // declared as public (due to pruning, we don't explore
                        // outside crate private modules => no need to check this)
                        if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
                            lookup_results.push(path);
                        }
                    }
                }
                // collect submodules to explore
                if let Some(module) = name_binding.module() {
                    // form the path
                    let path_segments = match module.parent_link {
                        NoParentLink => path_segments.clone(),
                        ModuleParentLink(_, name) => {
                            let mut paths = path_segments.clone();
                            let ident = ast::Ident::with_empty_ctxt(name);
                            let params = PathParameters::none();
                            let segm = PathSegment {
                                identifier: ident,
                                parameters: params,
                            };
                            paths.push(segm);
                            paths
                        }
                        _ => bug!(),
                    };
                    if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
                        // add the module to the lookup
                        let is_extern = in_module_is_extern || name_binding.is_extern_crate();
                        if !worklist.iter().any(|&(m, _, _)| m.def == module.def) {
                            worklist.push((module, path_segments, is_extern));
                        }
                    }
                }
            })
        }
        SuggestedCandidates {
            name: lookup_name.as_str().to_string(),
            candidates: lookup_results,
        }
    }
fn lookup_candidates < FilterFn > ( & mut self , lookup_name : Name , namespace : Namespace , filter_fn : FilterFn ) -> SuggestedCandidates where FilterFn : Fn ( Def ) -> bool { let mut lookup_results = Vec :: new ( ) ; let mut worklist = Vec :: new ( ) ; worklist . push ( ( self . graph_root , Vec :: new ( ) , false ) ) ; while let Some ( ( in_module , path_segments , in_module_is_extern ) ) = worklist . pop ( ) { self . populate_module_if_necessary ( in_module ) ; in_module . for_each_child ( | name , ns , name_binding | { // avoid imports entirely if name_binding . is_import ( ) { return ; } // collect results based on the filter function if let Some ( def ) = name_binding . def ( ) { if name == lookup_name && ns == namespace && filter_fn ( def ) { // create the path let ident = ast :: Ident :: with_empty_ctxt ( name ) ; let params = PathParameters :: none ( ) ; let segment = PathSegment { identifier : ident , parameters : params , } ; let span = name_binding . span ; let mut segms = path_segments . clone ( ) ; segms . push ( segment ) ; let path = Path { span : span , global : true , segments : segms , } ; // the entity is accessible in the following cases: // 1. if it's defined in the same crate, it's always // accessible (since private entities can be made public) // 2. if it's defined in another crate, it's accessible // only if both the module is public and the entity is // declared as public (due to pruning, we don't explore // outside crate private modules => no need to check this) if ! in_module_is_extern || name_binding . vis == ty :: Visibility :: Public { lookup_results . push ( path ) ; } } } // collect submodules to explore if let Some ( module ) = name_binding . module ( ) { // form the path let path_segments = match module . parent_link { NoParentLink => path_segments . clone ( ) , ModuleParentLink ( _ , name ) => { let mut paths = path_segments . clone ( ) ; let ident = ast :: Ident :: with_empty_ctxt ( name ) ; let params = PathParameters :: none ( ) ; let segm = PathSegment { identifier : ident , parameters : params , } ; paths . push ( segm ) ; paths } _ => bug ! ( ) , } ; if ! in_module_is_extern || name_binding . vis == ty :: Visibility :: Public { // add the module to the lookup let is_extern = in_module_is_extern || name_binding . is_extern_crate ( ) ; if ! worklist . iter ( ) . any ( | & ( m , _ , _ ) | m . def == module . def ) { worklist . push ( ( module , path_segments , is_extern ) ) ; } } } } ) } SuggestedCandidates { name : lookup_name . as_str ( ) . to_string ( ) , candidates : lookup_results , } }
When name resolution fails, this method can be used to look up candidate
entities with the expected name.
When name resolution fails this method can be used to look up candidate entities with the expected name .
&mut self
lookup_name
Name
namespace
Namespace
filter_fn
FilterFn