@@ -1424,74 +1424,68 @@ struct RootCollector<'a, 'tcx> {
14241424 entry_fn: Option<(DefId, EntryFnType)>,
14251425}
14261426
1427- impl<'v > RootCollector<'_, 'v > {
1427+ impl<'tcx > RootCollector<'_, 'tcx > {
14281428 fn process_item(&mut self, id: hir::ItemId) {
1429- match self.tcx.def_kind(id.owner_id) {
1429+ let tcx = self.tcx;
1430+ let def_id = id.owner_id.to_def_id();
1431+
1432+ match tcx.def_kind(def_id) {
14301433 DefKind::Enum | DefKind::Struct | DefKind::Union => {
1431- if self.strategy == MonoItemCollectionStrategy::Eager
1432- && !self.tcx.generics_of(id.owner_id).requires_monomorphization(self.tcx)
1433- {
1434- debug!("RootCollector: ADT drop-glue for `{id:?}`",);
1435- let id_args =
1436- ty::GenericArgs::for_item(self.tcx, id.owner_id.to_def_id(), |param, _| {
1437- match param.kind {
1438- GenericParamDefKind::Lifetime => {
1439- self.tcx.lifetimes.re_erased.into()
1440- }
1441- GenericParamDefKind::Type { .. }
1442- | GenericParamDefKind::Const { .. } => {
1443- unreachable!(
1444- "`own_requires_monomorphization` check means that \
1445- we should have no type/const params"
1446- )
1447- }
1448- }
1449- });
1450-
1451- // This type is impossible to instantiate, so we should not try to
1452- // generate a `drop_in_place` instance for it.
1453- if self.tcx.instantiate_and_check_impossible_predicates((
1454- id.owner_id.to_def_id(),
1455- id_args,
1456- )) {
1457- return;
1458- }
1434+ if self.strategy == MonoItemCollectionStrategy::Lazy {
1435+ return;
1436+ }
14591437
1460- let ty =
1461- self.tcx.type_of(id.owner_id.to_def_id()).instantiate(self.tcx, id_args);
1462- assert!(!ty.has_non_region_param());
1463- visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output);
1438+ if tcx.generics_of(def_id).own_requires_monomorphization() {
1439+ return;
1440+ }
1441+ let args = ty::GenericArgs::for_item(tcx, def_id, |param, _| {
1442+ expect_and_erase_regions(tcx, param)
1443+ });
1444+ if tcx.instantiate_and_check_impossible_predicates((def_id, args)) {
1445+ return;
14641446 }
1447+
1448+ let ty = tcx.type_of(def_id).instantiate(tcx, args);
1449+ debug_assert!(!ty.has_non_region_param());
1450+
1451+ debug!("RootCollector: ADT drop-glue for `{id:?}`");
1452+ visit_drop_use(tcx, ty, true, DUMMY_SP, self.output);
14651453 }
14661454 DefKind::GlobalAsm => {
1467- debug!(
1468- "RootCollector: ItemKind::GlobalAsm({})",
1469- self.tcx.def_path_str(id.owner_id)
1470- );
1455+ debug!("RootCollector: ItemKind::GlobalAsm({})", tcx.def_path_str(def_id));
14711456 self.output.push(dummy_spanned(MonoItem::GlobalAsm(id)));
14721457 }
14731458 DefKind::Static { .. } => {
1474- let def_id = id.owner_id.to_def_id();
1475- debug!("RootCollector: ItemKind::Static({})", self.tcx.def_path_str(def_id));
1459+ debug!("RootCollector: ItemKind::Static({})", tcx.def_path_str(def_id));
14761460 self.output.push(dummy_spanned(MonoItem::Static(def_id)));
14771461 }
14781462 DefKind::Const => {
14791463 // Const items only generate mono items if they are actually used somewhere.
14801464 // Just declaring them is insufficient.
1481-
14821465 // If we're collecting items eagerly, then recurse into all constants.
14831466 // Otherwise the value is only collected when explicitly mentioned in other items.
1484- if self.strategy == MonoItemCollectionStrategy::Eager {
1485- if !self.tcx.generics_of(id.owner_id).own_requires_monomorphization()
1486- && let Ok(val) = self.tcx.const_eval_poly(id.owner_id.to_def_id())
1487- {
1488- collect_const_value(self. tcx, val, self.output);
1489- }
1467+ if self.strategy == MonoItemCollectionStrategy::Lazy {
1468+ return;
1469+ }
1470+
1471+ if tcx.generics_of(def_id).own_requires_monomorphization() {
1472+ return;
14901473 }
1474+
1475+ let args = ty::GenericArgs::for_item(tcx, def_id, |param, _| {
1476+ expect_and_erase_regions(tcx, param)
1477+ });
1478+ if tcx.instantiate_and_check_impossible_predicates((def_id, args)) {
1479+ return;
1480+ }
1481+
1482+ let Ok(val) = tcx.const_eval_poly(def_id) else { return };
1483+
1484+ collect_const_value(tcx, val, self.output);
14911485 }
14921486 DefKind::Impl { .. } => {
14931487 if self.strategy == MonoItemCollectionStrategy::Eager {
1494- create_mono_items_for_default_impls(self. tcx, id, self.output);
1488+ create_mono_items_for_default_impls(tcx, id, self.output);
14951489 }
14961490 }
14971491 DefKind::Fn => {
@@ -1614,35 +1608,23 @@ fn create_mono_items_for_default_impls<'tcx>(
16141608 item: hir::ItemId,
16151609 output: &mut MonoItems<'tcx>,
16161610) {
1617- let Some(impl_) = tcx.impl_trait_header(item.owner_id) else {
1618- return;
1619- };
1620-
1611+ let impl_def_id = item.owner_id.to_def_id();
1612+ let Some(impl_) = tcx.impl_trait_header(impl_def_id) else { return };
16211613 if matches!(impl_.polarity, ty::ImplPolarity::Negative) {
16221614 return;
16231615 }
16241616
1625- if tcx.generics_of(item.owner_id).own_requires_monomorphization() {
1626- return;
1627- }
1628-
16291617 // Lifetimes never affect trait selection, so we are allowed to eagerly
16301618 // instantiate an instance of an impl method if the impl (and method,
16311619 // which we check below) is only parameterized over lifetime. In that case,
16321620 // we use the ReErased, which has no lifetime information associated with
16331621 // it, to validate whether or not the impl is legal to instantiate at all.
1634- let only_region_params = |param: &ty::GenericParamDef, _: &_| match param.kind {
1635- GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
1636- GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
1637- unreachable!(
1638- "`own_requires_monomorphization` check means that \
1639- we should have no type/const params"
1640- )
1641- }
1642- };
1643- let impl_args = GenericArgs::for_item(tcx, item.owner_id.to_def_id(), only_region_params);
1644- let trait_ref = impl_.trait_ref.instantiate(tcx, impl_args);
1645-
1622+ if tcx.generics_of(impl_def_id).own_requires_monomorphization() {
1623+ return;
1624+ }
1625+ let impl_args = ty::GenericArgs::for_item(tcx, impl_def_id, |param, _| {
1626+ expect_and_erase_regions(tcx, param)
1627+ });
16461628 // Unlike 'lazy' monomorphization that begins by collecting items transitively
16471629 // called by `main` or other global items, when eagerly monomorphizing impl
16481630 // items, we never actually check that the predicates of this impl are satisfied
@@ -1652,13 +1634,15 @@ fn create_mono_items_for_default_impls<'tcx>(
16521634 // consider higher-ranked predicates such as `for<'a> &'a mut [u8]: Copy` to
16531635 // be trivially false. We must now check that the impl has no impossible-to-satisfy
16541636 // predicates.
1655- if tcx.instantiate_and_check_impossible_predicates((item.owner_id.to_def_id() , impl_args)) {
1637+ if tcx.instantiate_and_check_impossible_predicates((impl_def_id , impl_args)) {
16561638 return;
16571639 }
16581640
1641+ let trait_ref = impl_.trait_ref.instantiate(tcx, impl_args);
1642+
16591643 let typing_env = ty::TypingEnv::fully_monomorphized();
16601644 let trait_ref = tcx.normalize_erasing_regions(typing_env, trait_ref);
1661- let overridden_methods = tcx.impl_item_implementor_ids(item.owner_id );
1645+ let overridden_methods = tcx.impl_item_implementor_ids(impl_def_id );
16621646 for method in tcx.provided_trait_methods(trait_ref.def_id) {
16631647 if overridden_methods.contains_key(&method.def_id) {
16641648 continue;
@@ -1671,7 +1655,9 @@ fn create_mono_items_for_default_impls<'tcx>(
16711655 // As mentioned above, the method is legal to eagerly instantiate if it
16721656 // only has lifetime generic parameters. This is validated by calling
16731657 // `own_requires_monomorphization` on both the impl and method.
1674- let args = trait_ref.args.extend_to(tcx, method.def_id, only_region_params);
1658+ let args = trait_ref
1659+ .args
1660+ .extend_to(tcx, method.def_id, |param, _| expect_and_erase_regions(tcx, param));
16751661 let instance = ty::Instance::expect_resolve(tcx, typing_env, method.def_id, args, DUMMY_SP);
16761662
16771663 let mono_item = create_fn_mono_item(tcx, instance, DUMMY_SP);
@@ -1681,6 +1667,18 @@ fn create_mono_items_for_default_impls<'tcx>(
16811667 }
16821668}
16831669
1670+ fn expect_and_erase_regions<'tcx>(
1671+ tcx: TyCtxt<'tcx>,
1672+ param: &ty::GenericParamDef,
1673+ ) -> ty::GenericArg<'tcx> {
1674+ match param.kind {
1675+ GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
1676+ GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
1677+ bug!("unexpected non-region param")
1678+ }
1679+ }
1680+ }
1681+
16841682//=-----------------------------------------------------------------------------
16851683// Top-level entry point, tying it all together
16861684//=-----------------------------------------------------------------------------
0 commit comments