/// Attempts to resolve an obligation. The result is a shallow vtable resolution -- meaning that we
/// do not (necessarily) resolve all nested obligations on the impl. Note that type check should
/// guarantee to us that all nested obligations *could be* resolved if we wanted to.
Attempts to resolve an obligation. The result is a shallow vtable resolution -- meaning that we
do not (necessarily) resolve all nested obligations on the impl. Note that type check should
guarantee to us that all nested obligations *could be* resolved if we wanted to.
Attempts to resolve an obligation . The result is a shallow vtable resolution -- meaning that we do not ( necessarily ) resolve all nested obligations on the impl . Note that type check should guarantee to us that all nested obligations * could be * resolved if we wanted to .
pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                    span: Span,
                                    trait_ref: ty::PolyTraitRef<'tcx>)
                                    -> traits::Vtable<'tcx, ()>
{
    let tcx = ccx.tcx();
    // Remove any references to regions; this helps improve caching.
    let trait_ref = erase_regions(tcx, &trait_ref);
    // First check the cache.
    match ccx.trait_cache().borrow().get(&trait_ref) {
        Some(vtable) => {
            info!("Cache hit: {:?}", trait_ref);
            return (*vtable).clone();
        }
        None => { }
    }
    debug!("trans fulfill_obligation: trait_ref={:?} def_id={:?}",
           trait_ref, trait_ref.def_id());
    // Do the initial selection for the obligation. This yields the
    // shallow result we are looking for -- that is, what specific impl.
    let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
    let mut selcx = traits::SelectionContext::new(&infcx);
    let obligation =
        traits::Obligation::new(traits::ObligationCause::misc(span, ast::DUMMY_NODE_ID),
                                trait_ref.to_poly_trait_predicate());
    let selection = match selcx.select(&obligation) {
        Ok(Some(selection)) => selection,
        Ok(None) => {
            // Ambiguity can happen when monomorphizing during trans
            // expands to some humongo type that never occurred
            // statically -- this humongo type can then overflow,
            // leading to an ambiguous result. So report this as an
            // overflow bug, since I believe this is the only case
            // where ambiguity can result.
            debug!("Encountered ambiguity selecting `{:?}` during trans, \
                    presuming due to overflow",
                   trait_ref);
            ccx.sess().span_fatal(
                span,
                "reached the recursion limit during monomorphization");
        }
        Err(e) => {
            tcx.sess.span_bug(
                span,
                &format!("Encountered error `{:?}` selecting `{:?}` during trans",
                        e,
                        trait_ref))
        }
    };
    // Currently, we use a fulfillment context to completely resolve
    // all nested obligations. This is because they can inform the
    // inference of the impl's type parameters.
    let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
    let vtable = selection.map(|predicate| {
        fulfill_cx.register_predicate_obligation(&infcx, predicate);
    });
    let vtable = erase_regions(tcx,
        &drain_fulfillment_cx_or_panic(span, &infcx, &mut fulfill_cx, &vtable)
    );
    info!("Cache miss: {:?} => {:?}", trait_ref, vtable);
    ccx.trait_cache().borrow_mut().insert(trait_ref, vtable.clone());
    vtable
}
pub fn fulfill_obligation < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > , span : Span , trait_ref : ty :: PolyTraitRef < ' tcx > ) -> traits :: Vtable < ' tcx , ( ) > { let tcx = ccx . tcx ( ) ; // Remove any references to regions; this helps improve caching. let trait_ref = erase_regions ( tcx , & trait_ref ) ; // First check the cache. match ccx . trait_cache ( ) . borrow ( ) . get ( & trait_ref ) { Some ( vtable ) => { info ! ( " " trait_ref ) ; return ( * vtable ) . clone ( ) ; } None => { } } debug ! ( " " trait_ref trait_ref def_id ( ) ) ; // Do the initial selection for the obligation. This yields the // shallow result we are looking for -- that is, what specific impl. let infcx = infer :: normalizing_infer_ctxt ( tcx , & tcx . tables ) ; let mut selcx = traits :: SelectionContext :: new ( & infcx ) ; let obligation = traits :: Obligation :: new ( traits :: ObligationCause :: misc ( span , ast :: DUMMY_NODE_ID ) , trait_ref . to_poly_trait_predicate ( ) ) ; let selection = match selcx . select ( & obligation ) { Ok ( Some ( selection ) ) => selection , Ok ( None ) => { // Ambiguity can happen when monomorphizing during trans // expands to some humongo type that never occurred // statically -- this humongo type can then overflow, // leading to an ambiguous result. So report this as an // overflow bug, since I believe this is the only case // where ambiguity can result. debug ! ( " \
 " trait_ref ) ; ccx . sess ( ) . span_fatal ( span , " " ) ; } Err ( e ) => { tcx . sess . span_bug ( span , & format ! ( " " e trait_ref ) ) } } ; // Currently, we use a fulfillment context to completely resolve // all nested obligations. This is because they can inform the // inference of the impl's type parameters. let mut fulfill_cx = infcx . fulfillment_cx . borrow_mut ( ) ; let vtable = selection . map ( | predicate | { fulfill_cx . register_predicate_obligation ( & infcx , predicate ) ; } ) ; let vtable = erase_regions ( tcx , & drain_fulfillment_cx_or_panic ( span , & infcx , & mut fulfill_cx , & vtable ) ) ; info ! ( " " trait_ref vtable ) ; ccx . trait_cache ( ) . borrow_mut ( ) . insert ( trait_ref , vtable . clone ( ) ) ; vtable }
Attempts to resolve an obligation.
Attempts to resolve an obligation .
ccx
&CrateContext<'a, 'tcx>
span
Span
trait_ref
ty::PolyTraitRef<'tcx>