You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: pipeline.rs
    path of file: ./repos/pavex/libs/pavexc/src/compiler/analyses/processing_pipeline
    
    the code of the file until where you have to start completion: use std::collections::BTreeMap;

use ahash::{HashMap, HashMapExt};
use guppy::graph::PackageGraph;
use guppy::PackageId;
use indexmap::{IndexMap, IndexSet};

use pavex_bp_schema::{CloningStrategy, Lifecycle};

use crate::compiler::analyses::call_graph::{
    request_scoped_call_graph, request_scoped_ordered_call_graph, CallGraphNode,
    InputParameterSource, OrderedCallGraph, RawCallGraph,
};
use crate::compiler::analyses::components::HydratedComponent;
use crate::compiler::analyses::components::{ComponentDb, ComponentId};
use crate::compiler::analyses::computations::ComputationDb;
use crate::compiler::analyses::constructibles::Constructible
    
fn get_next_field_types(long_lived_types: &IndexSet<ResolvedType>) -> IndexSet<ResolvedType> {
    let mut inner_type2by_value: IndexMap<&ResolvedType, bool> = IndexMap::new();
    for ty_ in long_lived_types {
        if let ResolvedType::Reference(ref_) = ty_ {
            if !ref_.lifetime.is_static() {
                inner_type2by_value
                    .entry(ref_.inner.as_ref())
                    .or_insert(false);
                continue;
            }
        }
        inner_type2by_value.insert(ty_, true);
    }
    inner_type2by_value
        .into_iter()
        .map(|(ty_, by_value)| {
            let ty_ = ty_.to_owned();
            if by_value {
                ty_
            } else {
                ResolvedType::Reference(TypeReference {
                    is_mutable: false,
                    lifetime: Lifetime::Elided,
                    inner: Box::new(ty_),
                })
            }
        })
        .collect()
}