diff options
Diffstat (limited to 'compiler/rustc_ty_utils/src')
| -rw-r--r-- | compiler/rustc_ty_utils/src/assoc.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/implied_bounds.rs | 129 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/instance.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/layout.rs | 40 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/ty.rs | 34 |
5 files changed, 112 insertions, 99 deletions
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 780f7ea426f..3e140793b5a 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -192,7 +192,8 @@ fn associated_types_for_impl_traits_in_associated_fn( if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind && self.rpits.insert(item_id.owner_id.def_id) { - let opaque_item = self.tcx.hir().expect_item(item_id.owner_id.def_id).expect_opaque_ty(); + let opaque_item = + self.tcx.hir().expect_item(item_id.owner_id.def_id).expect_opaque_ty(); for bound in opaque_item.bounds { intravisit::walk_param_bound(self, bound); } diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index ec2e0daaf88..0ca7d43f6d5 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -50,73 +50,76 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' let mut impl_spans = impl_spans(tcx, def_id); tcx.arena.alloc_from_iter(tys.into_iter().map(|ty| (ty, impl_spans.next().unwrap()))) } - DefKind::AssocTy if let Some(data) = tcx.opt_rpitit_info(def_id.to_def_id()) => match data { - ty::ImplTraitInTraitData::Trait { fn_def_id, .. } => { - // We need to remap all of the late-bound lifetimes in theassumed wf types - // of the fn (which are represented as ReFree) to the early-bound lifetimes - // of the RPITIT (which are represented by ReEarlyBound owned by the opaque). - // Luckily, this is very easy to do because we already have that mapping - // stored in the HIR of this RPITIT. - // - // Side-note: We don't really need to do this remapping for early-bound - // lifetimes because they're already "linked" by the bidirectional outlives - // predicates we insert in the `explicit_predicates_of` query for RPITITs. - let mut mapping = FxHashMap::default(); - let generics = tcx.generics_of(def_id); + DefKind::AssocTy if let Some(data) = tcx.opt_rpitit_info(def_id.to_def_id()) => { + match data { + ty::ImplTraitInTraitData::Trait { fn_def_id, .. } => { + // We need to remap all of the late-bound lifetimes in theassumed wf types + // of the fn (which are represented as ReFree) to the early-bound lifetimes + // of the RPITIT (which are represented by ReEarlyBound owned by the opaque). + // Luckily, this is very easy to do because we already have that mapping + // stored in the HIR of this RPITIT. + // + // Side-note: We don't really need to do this remapping for early-bound + // lifetimes because they're already "linked" by the bidirectional outlives + // predicates we insert in the `explicit_predicates_of` query for RPITITs. + let mut mapping = FxHashMap::default(); + let generics = tcx.generics_of(def_id); - // For each captured opaque lifetime, if it's late-bound (`ReFree` in this case, - // since it has been liberated), map it back to the early-bound lifetime of - // the GAT. Since RPITITs also have all of the fn's generics, we slice only - // the end of the list corresponding to the opaque's generics. - for param in &generics.params[tcx.generics_of(fn_def_id).params.len()..] { - let orig_lt = tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()); - if matches!(*orig_lt, ty::ReFree(..)) { - mapping.insert( - orig_lt, - ty::Region::new_early_bound( - tcx, - ty::EarlyBoundRegion { - def_id: param.def_id, - index: param.index, - name: param.name, - }, - ), - ); + // For each captured opaque lifetime, if it's late-bound (`ReFree` in this case, + // since it has been liberated), map it back to the early-bound lifetime of + // the GAT. Since RPITITs also have all of the fn's generics, we slice only + // the end of the list corresponding to the opaque's generics. + for param in &generics.params[tcx.generics_of(fn_def_id).params.len()..] { + let orig_lt = + tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()); + if matches!(*orig_lt, ty::ReFree(..)) { + mapping.insert( + orig_lt, + ty::Region::new_early_bound( + tcx, + ty::EarlyBoundRegion { + def_id: param.def_id, + index: param.index, + name: param.name, + }, + ), + ); + } } + // FIXME: This could use a real folder, I guess. + let remapped_wf_tys = tcx.fold_regions( + tcx.assumed_wf_types(fn_def_id.expect_local()).to_vec(), + |region, _| { + // If `region` is a `ReFree` that is captured by the + // opaque, remap it to its corresponding the early- + // bound region. + if let Some(remapped_region) = mapping.get(®ion) { + *remapped_region + } else { + region + } + }, + ); + tcx.arena.alloc_from_iter(remapped_wf_tys) + } + // Assumed wf types for RPITITs in an impl just inherit (and instantiate) + // the assumed wf types of the trait's RPITIT GAT. + ty::ImplTraitInTraitData::Impl { .. } => { + let impl_def_id = tcx.local_parent(def_id); + let rpitit_def_id = tcx.associated_item(def_id).trait_item_def_id.unwrap(); + let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto( + tcx, + impl_def_id.to_def_id(), + tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity().args, + ); + tcx.arena.alloc_from_iter( + ty::EarlyBinder::bind(tcx.assumed_wf_types_for_rpitit(rpitit_def_id)) + .iter_instantiated_copied(tcx, args) + .chain(tcx.assumed_wf_types(impl_def_id).into_iter().copied()), + ) } - // FIXME: This could use a real folder, I guess. - let remapped_wf_tys = tcx.fold_regions( - tcx.assumed_wf_types(fn_def_id.expect_local()).to_vec(), - |region, _| { - // If `region` is a `ReFree` that is captured by the - // opaque, remap it to its corresponding the early- - // bound region. - if let Some(remapped_region) = mapping.get(®ion) { - *remapped_region - } else { - region - } - }, - ); - tcx.arena.alloc_from_iter(remapped_wf_tys) - } - // Assumed wf types for RPITITs in an impl just inherit (and instantiate) - // the assumed wf types of the trait's RPITIT GAT. - ty::ImplTraitInTraitData::Impl { .. } => { - let impl_def_id = tcx.local_parent(def_id); - let rpitit_def_id = tcx.associated_item(def_id).trait_item_def_id.unwrap(); - let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto( - tcx, - impl_def_id.to_def_id(), - tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity().args, - ); - tcx.arena.alloc_from_iter( - ty::EarlyBinder::bind(tcx.assumed_wf_types_for_rpitit(rpitit_def_id)) - .iter_instantiated_copied(tcx, args) - .chain(tcx.assumed_wf_types(impl_def_id).into_iter().copied()), - ) } - }, + } DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)), DefKind::OpaqueTy => match tcx.def_kind(tcx.local_parent(def_id)) { DefKind::TyAlias => ty::List::empty(), diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 91f1c21310e..2fbf87800bb 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -188,10 +188,7 @@ fn resolve_associated_item<'tcx>( && trait_item_id != leaf_def.item.def_id && let Some(leaf_def_item) = leaf_def.item.def_id.as_local() { - tcx.compare_impl_const(( - leaf_def_item, - trait_item_id, - ))?; + tcx.compare_impl_const((leaf_def_item, trait_item_id))?; } Some(ty::Instance::new(leaf_def.item.def_id, args)) diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 8132742d1df..cc6c8478785 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -170,29 +170,27 @@ fn layout_of_uncached<'tcx>( // fall back to structurally deducing metadata. && !pointee.references_error() { - let pointee_metadata = Ty::new_projection(tcx,metadata_def_id, [pointee]); - let metadata_ty = match tcx.try_normalize_erasing_regions( - param_env, - pointee_metadata, - ) { - Ok(metadata_ty) => metadata_ty, - Err(mut err) => { - // Usually `<Ty as Pointee>::Metadata` can't be normalized because - // its struct tail cannot be normalized either, so try to get a - // more descriptive layout error here, which will lead to less confusing - // diagnostics. - match tcx.try_normalize_erasing_regions( - param_env, - tcx.struct_tail_without_normalization(pointee), - ) { - Ok(_) => {}, - Err(better_err) => { - err = better_err; + let pointee_metadata = Ty::new_projection(tcx, metadata_def_id, [pointee]); + let metadata_ty = + match tcx.try_normalize_erasing_regions(param_env, pointee_metadata) { + Ok(metadata_ty) => metadata_ty, + Err(mut err) => { + // Usually `<Ty as Pointee>::Metadata` can't be normalized because + // its struct tail cannot be normalized either, so try to get a + // more descriptive layout error here, which will lead to less confusing + // diagnostics. + match tcx.try_normalize_erasing_regions( + param_env, + tcx.struct_tail_without_normalization(pointee), + ) { + Ok(_) => {} + Err(better_err) => { + err = better_err; + } } + return Err(error(cx, LayoutError::NormalizationFailure(pointee, err))); } - return Err(error(cx, LayoutError::NormalizationFailure(pointee, err))); - }, - }; + }; let metadata_layout = cx.layout_of(metadata_ty)?; // If the metadata is a 1-zst, then the pointer is thin. diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index c22c67bd907..e1ec159921e 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -184,9 +184,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> { fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> { if let ty::Alias(ty::Projection, unshifted_alias_ty) = *ty.kind() - && let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. } - | ty::ImplTraitInTraitData::Impl { fn_def_id, .. }) - = self.tcx.opt_rpitit_info(unshifted_alias_ty.def_id) + && let Some( + ty::ImplTraitInTraitData::Trait { fn_def_id, .. } + | ty::ImplTraitInTraitData::Impl { fn_def_id, .. }, + ) = self.tcx.opt_rpitit_info(unshifted_alias_ty.def_id) && fn_def_id == self.fn_def_id && self.seen.insert(unshifted_alias_ty.def_id) { @@ -202,7 +203,11 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> { "we shouldn't walk non-predicate binders with `impl Trait`...", ); } - ty::Region::new_late_bound(self.tcx, index.shifted_out_to_binder(self.depth), bv) + ty::Region::new_late_bound( + self.tcx, + index.shifted_out_to_binder(self.depth), + bv, + ) } else { re } @@ -211,12 +216,21 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> { // If we're lowering to associated item, install the opaque type which is just // the `type_of` of the trait's associated item. If we're using the old lowering // strategy, then just reinterpret the associated type like an opaque :^) - let default_ty = self.tcx.type_of(shifted_alias_ty.def_id).instantiate(self.tcx, shifted_alias_ty.args); - - self.predicates.push(ty::Binder::bind_with_vars( - ty::ProjectionPredicate { projection_ty: shifted_alias_ty, term: default_ty.into() }, - self.bound_vars, - ).to_predicate(self.tcx)); + let default_ty = self + .tcx + .type_of(shifted_alias_ty.def_id) + .instantiate(self.tcx, shifted_alias_ty.args); + + self.predicates.push( + ty::Binder::bind_with_vars( + ty::ProjectionPredicate { + projection_ty: shifted_alias_ty, + term: default_ty.into(), + }, + self.bound_vars, + ) + .to_predicate(self.tcx), + ); // We walk the *un-shifted* alias ty, because we're tracking the de bruijn // binder depth, and if we were to walk `shifted_alias_ty` instead, we'd |
