fn add_constraints_from_ty(&mut self,
                               ty: ty::t,
                               variance: VarianceTermPtr<'a>) {
        debug!("add_constraints_from_ty(ty={})", ty.repr(self.tcx()));

        match ty::get(ty).sty {
            ty::ty_nil | ty::ty_bot | ty::ty_bool |
            ty::ty_char | ty::ty_int(_) | ty::ty_uint(_) |
            ty::ty_float(_) => {
                /* leaf type -- noop */
            }

            ty::ty_rptr(region, ref mt) => {
                let contra = self.contravariant(variance);
                self.add_constraints_from_region(region, contra);
                self.add_constraints_from_mt(mt, variance);
            }

            ty::ty_str(vstore) => {
                self.add_constraints_from_vstore(vstore, variance);
            }

            ty::ty_vec(ref mt, vstore) => {
                self.add_constraints_from_vstore(vstore, variance);
                self.add_constraints_from_mt(mt, variance);
            }

            ty::ty_uniq(typ) | ty::ty_box(typ) => {
                self.add_constraints_from_ty(typ, variance);
            }

            ty::ty_ptr(ref mt) => {
                self.add_constraints_from_mt(mt, variance);
            }

            ty::ty_tup(ref subtys) => {
                for &subty in subtys.iter() {
                    self.add_constraints_from_ty(subty, variance);
                }
            }

            ty::ty_enum(def_id, ref substs) |
            ty::ty_struct(def_id, ref substs) => {
                let item_type = ty::lookup_item_type(self.tcx(), def_id);
                self.add_constraints_from_substs(def_id, &item_type.generics,
                                                 substs, variance);
            }

            ty::ty_trait(def_id, ref substs, _, _, _) => {
                let trait_def = ty::lookup_trait_def(self.tcx(), def_id);
                self.add_constraints_from_substs(def_id, &trait_def.generics,
                                                 substs, variance);
            }

            ty::ty_param(ty::param_ty { def_id: ref def_id, .. }) => {
                assert_eq!(def_id.crate, ast::LOCAL_CRATE);
                match self.terms_cx.inferred_map.find(&def_id.node) {
                    Some(&index) => {
                        self.add_constraint(index, variance);
                    }
                    None => {
                        // We do not infer variance for type parameters
                        // declared on methods. They will not be present
                        // in the inferred_map.
                    }
                }
            }

            ty::ty_self(ref def_id) => {
                assert_eq!(def_id.crate, ast::LOCAL_CRATE);
                let index = self.inferred_index(def_id.node);
                self.add_constraint(index, variance);
            }

            ty::ty_bare_fn(ty::BareFnTy { sig: ref sig, .. }) => {
                self.add_constraints_from_sig(sig, variance);
            }

            ty::ty_closure(ty::ClosureTy { sig: ref sig, region, .. }) => {
                let contra = self.contravariant(variance);
                self.add_constraints_from_region(region, contra);
                self.add_constraints_from_sig(sig, variance);
            }

            ty::ty_infer(..) | ty::ty_err | ty::ty_type |
            ty::ty_opaque_closure_ptr(..) | ty::ty_unboxed_vec(..) => {
                self.tcx().sess.bug(
                    format!("Unexpected type encountered in \
                            variance inference: {}",
                            ty.repr(self.tcx())));
            }
        }
    }
/// Adds constraints appropriate for an instance of `ty` appearing
/// in a context with ambient variance `variance`
Adds constraints appropriate for an instance of `ty` appearing
in a context with ambient variance `variance`
Adds constraints appropriate for an instance of ` ty ` appearing in a context with ambient variance ` variance `
fn add_constraints_from_ty(&mut self,
                               ty: ty::t,
                               variance: VarianceTermPtr<'a>) {
        debug!("add_constraints_from_ty(ty={})", ty.repr(self.tcx()));
        match ty::get(ty).sty {
            ty::ty_nil | ty::ty_bot | ty::ty_bool |
            ty::ty_char | ty::ty_int(_) | ty::ty_uint(_) |
            ty::ty_float(_) => {
                /* leaf type -- noop */
            }
            ty::ty_rptr(region, ref mt) => {
                let contra = self.contravariant(variance);
                self.add_constraints_from_region(region, contra);
                self.add_constraints_from_mt(mt, variance);
            }
            ty::ty_str(vstore) => {
                self.add_constraints_from_vstore(vstore, variance);
            }
            ty::ty_vec(ref mt, vstore) => {
                self.add_constraints_from_vstore(vstore, variance);
                self.add_constraints_from_mt(mt, variance);
            }
            ty::ty_uniq(typ) | ty::ty_box(typ) => {
                self.add_constraints_from_ty(typ, variance);
            }
            ty::ty_ptr(ref mt) => {
                self.add_constraints_from_mt(mt, variance);
            }
            ty::ty_tup(ref subtys) => {
                for &subty in subtys.iter() {
                    self.add_constraints_from_ty(subty, variance);
                }
            }
            ty::ty_enum(def_id, ref substs) |
            ty::ty_struct(def_id, ref substs) => {
                let item_type = ty::lookup_item_type(self.tcx(), def_id);
                self.add_constraints_from_substs(def_id, &item_type.generics,
                                                 substs, variance);
            }
            ty::ty_trait(def_id, ref substs, _, _, _) => {
                let trait_def = ty::lookup_trait_def(self.tcx(), def_id);
                self.add_constraints_from_substs(def_id, &trait_def.generics,
                                                 substs, variance);
            }
            ty::ty_param(ty::param_ty { def_id: ref def_id, .. }) => {
                assert_eq!(def_id.crate, ast::LOCAL_CRATE);
                match self.terms_cx.inferred_map.find(&def_id.node) {
                    Some(&index) => {
                        self.add_constraint(index, variance);
                    }
                    None => {
                        // We do not infer variance for type parameters
                        // declared on methods. They will not be present
                        // in the inferred_map.
                    }
                }
            }
            ty::ty_self(ref def_id) => {
                assert_eq!(def_id.crate, ast::LOCAL_CRATE);
                let index = self.inferred_index(def_id.node);
                self.add_constraint(index, variance);
            }
            ty::ty_bare_fn(ty::BareFnTy { sig: ref sig, .. }) => {
                self.add_constraints_from_sig(sig, variance);
            }
            ty::ty_closure(ty::ClosureTy { sig: ref sig, region, .. }) => {
                let contra = self.contravariant(variance);
                self.add_constraints_from_region(region, contra);
                self.add_constraints_from_sig(sig, variance);
            }
            ty::ty_infer(..) | ty::ty_err | ty::ty_type |
            ty::ty_opaque_closure_ptr(..) | ty::ty_unboxed_vec(..) => {
                self.tcx().sess.bug(
                    format!("Unexpected type encountered in \
                            variance inference: {}",
                            ty.repr(self.tcx())));
            }
        }
    }
fn add_constraints_from_ty ( & mut self , ty : ty :: t , variance : VarianceTermPtr < ' a > ) { debug ! ( " " ty repr ( self tcx ( ) ) ) ; match ty :: get ( ty ) . sty { ty :: ty_nil | ty :: ty_bot | ty :: ty_bool | ty :: ty_char | ty :: ty_int ( _ ) | ty :: ty_uint ( _ ) | ty :: ty_float ( _ ) => { /* leaf type -- noop */ } ty :: ty_rptr ( region , ref mt ) => { let contra = self . contravariant ( variance ) ; self . add_constraints_from_region ( region , contra ) ; self . add_constraints_from_mt ( mt , variance ) ; } ty :: ty_str ( vstore ) => { self . add_constraints_from_vstore ( vstore , variance ) ; } ty :: ty_vec ( ref mt , vstore ) => { self . add_constraints_from_vstore ( vstore , variance ) ; self . add_constraints_from_mt ( mt , variance ) ; } ty :: ty_uniq ( typ ) | ty :: ty_box ( typ ) => { self . add_constraints_from_ty ( typ , variance ) ; } ty :: ty_ptr ( ref mt ) => { self . add_constraints_from_mt ( mt , variance ) ; } ty :: ty_tup ( ref subtys ) => { for & subty in subtys . iter ( ) { self . add_constraints_from_ty ( subty , variance ) ; } } ty :: ty_enum ( def_id , ref substs ) | ty :: ty_struct ( def_id , ref substs ) => { let item_type = ty :: lookup_item_type ( self . tcx ( ) , def_id ) ; self . add_constraints_from_substs ( def_id , & item_type . generics , substs , variance ) ; } ty :: ty_trait ( def_id , ref substs , _ , _ , _ ) => { let trait_def = ty :: lookup_trait_def ( self . tcx ( ) , def_id ) ; self . add_constraints_from_substs ( def_id , & trait_def . generics , substs , variance ) ; } ty :: ty_param ( ty :: param_ty { def_id : ref def_id , .. } ) => { assert_eq ! ( def_id crate ast LOCAL_CRATE ) ; match self . terms_cx . inferred_map . find ( & def_id . node ) { Some ( & index ) => { self . add_constraint ( index , variance ) ; } None => { // We do not infer variance for type parameters // declared on methods. They will not be present // in the inferred_map. } } } ty :: ty_self ( ref def_id ) => { assert_eq ! ( def_id crate ast LOCAL_CRATE ) ; let index = self . inferred_index ( def_id . node ) ; self . add_constraint ( index , variance ) ; } ty :: ty_bare_fn ( ty :: BareFnTy { sig : ref sig , .. } ) => { self . add_constraints_from_sig ( sig , variance ) ; } ty :: ty_closure ( ty :: ClosureTy { sig : ref sig , region , .. } ) => { let contra = self . contravariant ( variance ) ; self . add_constraints_from_region ( region , contra ) ; self . add_constraints_from_sig ( sig , variance ) ; } ty :: ty_infer ( .. ) | ty :: ty_err | ty :: ty_type | ty :: ty_opaque_closure_ptr ( .. ) | ty :: ty_unboxed_vec ( .. ) => { self . tcx ( ) . sess . bug ( format ! ( " \
 " ty repr ( self tcx ( ) ) ) ) ; } } }
Adds constraints appropriate for an instance of `ty` appearing
in a context with ambient variance `variance`
Adds constraints appropriate for an instance of ` ty ` appearing in a context with ambient variance ` variance `
&mut self
ty
ty::t
variance
VarianceTermPtr<'a>
&mut self
ty
ty::t
variance
VarianceTermPtr<'a>