|
1 | 1 | use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
2 | 2 | use crate::ty::print::{FmtPrinter, Printer};
|
| 3 | +use crate::ty::subst::InternalSubsts; |
3 | 4 | use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeFoldable};
|
4 | 5 | use rustc_errors::ErrorReported;
|
5 | 6 | use rustc_hir::def::Namespace;
|
@@ -106,32 +107,9 @@ pub enum InstanceDef<'tcx> {
|
106 | 107 | }
|
107 | 108 |
|
108 | 109 | impl<'tcx> Instance<'tcx> {
|
109 |
| - /// Returns the `Ty` corresponding to this `Instance`, |
110 |
| - /// with generic substitutions applied and lifetimes erased. |
111 |
| - /// |
112 |
| - /// This method can only be called when the 'substs' for this Instance |
113 |
| - /// are fully monomorphic (no `ty::Param`'s are present). |
114 |
| - /// This is usually the case (e.g. during codegen). |
115 |
| - /// However, during constant evaluation, we may want |
116 |
| - /// to try to resolve a `Instance` using generic parameters |
117 |
| - /// (e.g. when we are attempting to to do const-propagation). |
118 |
| - /// In this case, `Instance.ty_env` should be used to provide |
119 |
| - /// the `ParamEnv` for our generic context. |
120 |
| - pub fn monomorphic_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { |
121 |
| - let ty = tcx.type_of(self.def.def_id()); |
122 |
| - // There shouldn't be any params - if there are, then |
123 |
| - // Instance.ty_env should have been used to provide the proper |
124 |
| - // ParamEnv |
125 |
| - if self.substs.has_param_types_or_consts() { |
126 |
| - bug!("Instance.ty called for type {:?} with params in substs: {:?}", ty, self.substs); |
127 |
| - } |
128 |
| - tcx.subst_and_normalize_erasing_regions(self.substs, ty::ParamEnv::reveal_all(), &ty) |
129 |
| - } |
130 |
| - |
131 |
| - /// Like `Instance.ty`, but allows a `ParamEnv` to be specified for use during |
132 |
| - /// normalization. This method is only really useful during constant evaluation, |
133 |
| - /// where we are dealing with potentially generic types. |
134 |
| - pub fn ty_env(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> { |
| 110 | + /// Returns the `Ty` corresponding to this `Instance`, with generic substitutions applied and |
| 111 | + /// lifetimes erased, allowing a `ParamEnv` to be specified for use during normalization. |
| 112 | + pub fn ty(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> { |
135 | 113 | let ty = tcx.type_of(self.def.def_id());
|
136 | 114 | tcx.subst_and_normalize_erasing_regions(self.substs, param_env, &ty)
|
137 | 115 | }
|
@@ -486,6 +464,42 @@ impl<'tcx> Instance<'tcx> {
|
486 | 464 | | InstanceDef::VtableShim(..) => Some(self.substs),
|
487 | 465 | }
|
488 | 466 | }
|
| 467 | + |
| 468 | + /// Returns a new `Instance` where generic parameters in `instance.substs` are replaced by |
| 469 | + /// identify parameters if they are determined to be unused in `instance.def`. |
| 470 | + pub fn polymorphize(self, tcx: TyCtxt<'tcx>) -> Self { |
| 471 | + debug!("polymorphize: running polymorphization analysis"); |
| 472 | + if !tcx.sess.opts.debugging_opts.polymorphize { |
| 473 | + return self; |
| 474 | + } |
| 475 | + |
| 476 | + if let InstanceDef::Item(def) = self.def { |
| 477 | + let results = tcx.unused_generic_params(def.did); |
| 478 | + |
| 479 | + if results == 0 { |
| 480 | + // Exit early if every parameter was used. |
| 481 | + return self; |
| 482 | + } |
| 483 | + |
| 484 | + debug!("polymorphize: results={:064b}", results); |
| 485 | + let polymorphized_substs = |
| 486 | + InternalSubsts::for_item(tcx, def.did, |param, _| match param.kind { |
| 487 | + // If parameter is a const or type parameter.. |
| 488 | + ty::GenericParamDefKind::Const | ty::GenericParamDefKind::Type { .. } if |
| 489 | + // ..and is within range and unused.. |
| 490 | + param.index < 64 && ((results >> param.index) & 1) == 1 => |
| 491 | + // ..then use the identity for this parameter. |
| 492 | + tcx.mk_param_from_def(param), |
| 493 | + // Otherwise, use the parameter as before. |
| 494 | + _ => self.substs[param.index as usize], |
| 495 | + }); |
| 496 | + |
| 497 | + debug!("polymorphize: self={:?} polymorphized_substs={:?}", self, polymorphized_substs); |
| 498 | + Self { def: self.def, substs: polymorphized_substs } |
| 499 | + } else { |
| 500 | + self |
| 501 | + } |
| 502 | + } |
489 | 503 | }
|
490 | 504 |
|
491 | 505 | fn needs_fn_once_adapter_shim(
|
|
0 commit comments