99// except according to those terms.
1010
1111use rustc_data_structures:: indexed_vec:: IndexVec ;
12- use rustc:: ty:: { self , TyCtxt , Ty , TypeFoldable , Instance } ;
12+ use rustc:: ty:: { self , TyCtxt , Ty , ParamTy , TypeFoldable , Instance } ;
1313use rustc:: ty:: fold:: TypeFolder ;
1414use rustc:: ty:: subst:: Kind ;
1515use rustc:: middle:: const_val:: ConstVal ;
@@ -53,39 +53,31 @@ pub(crate) fn collapse_interchangable_instances<'a, 'tcx>(
5353 let used_substs = used_substs_for_instance ( tcx, instance) ;
5454 instance. substs = tcx. _intern_substs ( & instance. substs . into_iter ( ) . enumerate ( ) . map ( |( i, subst) | {
5555 if let Some ( ty) = subst. as_type ( ) {
56- /*let ty = if let ty::TyParam(ref _param) = ty.sty {
57- match used_substs.parameters[ParamIdx(i as u32)] {
58- ParamUsage::Unused => ty.into(),
59- ParamUsage::LayoutUsed | ParamUsage::Used => {
60- //^ Dont replace <closure_kind> and other internal params
61- if false /*param.name.as_str().starts_with("<")*/ {
62- ty.into()
63- } else {
64- tcx.sess.warn(&format!("Unused subst for {:?}", instance));
65- tcx.mk_ty(ty::TyNever)
56+ let ty = match used_substs. parameters [ ParamIdx ( i as u32 ) ] {
57+ ParamUsage :: Unused => {
58+ if false /*param.name.as_str().starts_with("<")*/ {
59+ ty. into ( )
60+ } else {
61+ #[ allow( unused_mut) ]
62+ let mut mir = Vec :: new ( ) ;
63+ :: util:: write_mir_pretty ( tcx, Some ( instance. def_id ( ) ) , & mut mir) . unwrap ( ) ;
64+ let mut generics = Some ( tcx. generics_of ( instance. def_id ( ) ) ) ;
65+ let mut pretty_generics = String :: new ( ) ;
66+ loop {
67+ if let Some ( ref gen) = generics {
68+ for ty in & gen. types {
69+ pretty_generics. push_str ( & format ! ( "{}:{} at {:?}, " , ty. index, ty. name, tcx. def_span( ty. def_id) ) ) ;
70+ }
71+ } else {
72+ break ;
73+ }
74+ generics = generics. and_then ( |gen|gen. parent ) . map ( |def_id|tcx. generics_of ( def_id) ) ;
6675 }
76+ tcx. sess . warn ( & format ! ( "Unused subst {} for {:?}<{}>\n with mir: {}" , i, instance, pretty_generics, String :: from_utf8_lossy( & mir) ) ) ;
77+ tcx. mk_ty ( ty:: TyNever )
6778 }
6879 }
69- } else {
70- tcx.sess.fatal("efjiofefio");
71- // Can't use TyError as it gives some ICE in rustc_trans::callee::get_fn
72- tcx.sess.warn(&format!("Unused subst for {:?}", instance));
73- tcx.mk_ty(ty::TyNever)
74- };*/
75- let ty = if used_substs. parameters [ ParamIdx ( i as u32 ) ] != ParamUsage :: Unused {
76- ty. into ( )
77- } else if let ty:: TyParam ( ref _param) = ty. sty {
78- //^ Dont replace <closure_kind> and other internal params
79- if false /*param.name.as_str().starts_with("<")*/ {
80- ty. into ( )
81- } else {
82- tcx. sess . warn ( & format ! ( "Unused subst for {:?}" , instance) ) ;
83- tcx. mk_ty ( ty:: TyNever )
84- }
85- } else {
86- // Can't use TyError as it gives some ICE in rustc_trans::callee::get_fn
87- tcx. sess . warn ( & format ! ( "Unused subst for {:?}" , instance) ) ;
88- tcx. mk_ty ( ty:: TyNever )
80+ ParamUsage :: LayoutUsed | ParamUsage :: Used => ty. into ( ) ,
8981 } ;
9082 Kind :: from ( ty)
9183 } else {
@@ -185,28 +177,64 @@ impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for SubstsVisitor<'a,
185177 return ty;
186178 }
187179 match ty. sty {
188- ty:: TyParam ( param) => {
189- self . 2 . parameters [ ParamIdx ( param. idx ) ] = ParamUsage :: Used ;
190- ty
180+ /*ty::TyAdt(_, substs) => {
181+ for subst in substs {
182+ if let Some(ty) = subst.as_type() {
183+ ty.fold_with(self);
184+ }
185+ }
186+ }
187+ ty::TyArray(ty, _) |
188+ ty::TySlice(ty) |
189+ ty::TyRawPtr(TypeAndMut { ty, .. }) |
190+ ty::TyRef(_, TypeAndMut { ty, .. }) => {
191+ ty.fold_with(self);
191192 }
192193 ty::TyFnDef(_, substs) => {
193194 for subst in substs {
194195 if let Some(ty) = subst.as_type() {
195196 ty.fold_with(self);
196197 }
197198 }
198- ty. super_fold_with ( self )
199+ }
200+ ty::TyFnPtr(poly_fn_sig) => {
201+ for ty in poly_fn_sig.skip_binder().inputs_and_outputs {
202+ ty.fold_with(self);
203+ }
199204 }
200205 ty::TyClosure(_, closure_substs) => {
201206 for subst in closure_substs.substs {
202207 if let Some(ty) = subst.as_type() {
203208 ty.fold_with(self);
204209 }
205210 }
206- ty. super_fold_with ( self )
207211 }
208- _ => ty. super_fold_with ( self )
212+ ty::TyGenerator(_, closure_substs, generator_interior) => {
213+ for subst in closure_substs.substs {
214+ if let Some(ty) = subst.as_type() {
215+ ty.fold_with(self);
216+ }
217+ }
218+ generator_interior.witness.fold_with(self);
219+ }
220+ ty::TyTuple(types, _) => {
221+ for ty in types {
222+ ty.fold_with(self);
223+ }
224+ }
225+ ty::TyProjection(projection_ty) => {
226+ for subst in projection_ty.substs {
227+ if let Some(ty) = subst.as_type() {
228+ ty.fold_with(self);
229+ }
230+ }
231+ }*/
232+ ty:: TyParam ( param) => {
233+ self . 2 . parameters [ ParamIdx ( param. idx ) ] = ParamUsage :: Used ;
234+ }
235+ _ => { }
209236 }
237+ ty. super_fold_with ( self )
210238 }
211239}
212240
@@ -215,13 +243,21 @@ fn used_substs_for_instance<'a, 'tcx: 'a>(
215243 instance : Instance < ' tcx > ,
216244) -> ParamsUsage {
217245 let mir = tcx. instance_mir ( instance. def ) ;
246+ let generics = tcx. generics_of ( instance. def_id ( ) ) ;
218247 let sig = :: rustc:: ty:: ty_fn_sig ( tcx, instance. ty ( tcx) ) ;
219248 let sig = tcx. erase_late_bound_regions_and_normalize ( & sig) ;
220249 let mut substs_visitor = SubstsVisitor ( tcx, mir, ParamsUsage :: new ( instance. substs . len ( ) ) ) ;
221- substs_visitor. visit_mir ( mir) ;
250+ //substs_visitor.visit_mir(mir);
251+ mir. fold_with ( & mut substs_visitor) ;
222252 for ty in sig. inputs ( ) . iter ( ) {
223253 ty. fold_with ( & mut substs_visitor) ;
224254 }
255+ for ty_param_def in & generics. types {
256+ if ParamTy :: for_def ( ty_param_def) . is_self ( ) {
257+ // The self parameter is important for trait selection
258+ ( substs_visitor. 2 ) . parameters [ ParamIdx ( ty_param_def. index ) ] = ParamUsage :: Used ;
259+ }
260+ }
225261 sig. output ( ) . fold_with ( & mut substs_visitor) ;
226262 substs_visitor. 2
227263}
0 commit comments