1
Fork 0

Rollup merge of #122103 - compiler-errors:taits-capture-everything, r=oli-obk

Make TAITs and ATPITs capture late-bound lifetimes in scope

This generalizes the behavior that RPITs have, where they duplicate their in-scope lifetimes so that they will always *reify* late-bound lifetimes that they capture. This allows TAITs and ATPITs to properly error when they capture in-scope late-bound lifetimes.

r? `@oli-obk` cc `@aliemjay`

Fixes #122093 and therefore https://github.com/rust-lang/rust/pull/120700#issuecomment-1981213868
This commit is contained in:
Matthias Krüger 2024-03-08 08:19:20 +01:00 committed by GitHub
commit d4d18d240b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 148 additions and 185 deletions

View file

@ -1254,7 +1254,7 @@ impl<'tcx> TyCtxt<'tcx> {
if self.def_kind(scope) == DefKind::OpaqueTy {
// Lifetime params of opaque types are synthetic and thus irrelevant to
// diagnostics. Map them back to their origin!
region = self.map_rpit_lifetime_to_fn_lifetime(def_id);
region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
continue;
}
break (scope, ty::BrNamed(def_id.into(), self.item_name(def_id.into())));
@ -2219,31 +2219,31 @@ impl<'tcx> TyCtxt<'tcx> {
)
}
/// Given the def-id of an early-bound lifetime on an RPIT corresponding to
/// Given the def-id of an early-bound lifetime on an opaque corresponding to
/// a duplicated captured lifetime, map it back to the early- or late-bound
/// lifetime of the function from which it originally as captured. If it is
/// a late-bound lifetime, this will represent the liberated (`ReLateParam`) lifetime
/// of the signature.
// FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just
// re-use the generics of the opaque, this function will need to be tweaked slightly.
pub fn map_rpit_lifetime_to_fn_lifetime(
pub fn map_opaque_lifetime_to_parent_lifetime(
self,
mut rpit_lifetime_param_def_id: LocalDefId,
mut opaque_lifetime_param_def_id: LocalDefId,
) -> ty::Region<'tcx> {
debug_assert!(
matches!(self.def_kind(rpit_lifetime_param_def_id), DefKind::LifetimeParam),
"{rpit_lifetime_param_def_id:?} is a {}",
self.def_descr(rpit_lifetime_param_def_id.to_def_id())
matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
"{opaque_lifetime_param_def_id:?} is a {}",
self.def_descr(opaque_lifetime_param_def_id.to_def_id())
);
loop {
let parent = self.local_parent(rpit_lifetime_param_def_id);
let parent = self.local_parent(opaque_lifetime_param_def_id);
let hir::OpaqueTy { lifetime_mapping, .. } =
self.hir_node_by_def_id(parent).expect_item().expect_opaque_ty();
let Some((lifetime, _)) = lifetime_mapping
.iter()
.find(|(_, duplicated_param)| *duplicated_param == rpit_lifetime_param_def_id)
.find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
else {
bug!("duplicated lifetime param should be present");
};
@ -2256,7 +2256,7 @@ impl<'tcx> TyCtxt<'tcx> {
// of the opaque we mapped from. Continue mapping.
if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
debug_assert_eq!(self.parent(parent.to_def_id()), new_parent);
rpit_lifetime_param_def_id = ebv.expect_local();
opaque_lifetime_param_def_id = ebv.expect_local();
continue;
}

View file

@ -1940,18 +1940,6 @@ impl<'tcx> TyCtxt<'tcx> {
matches!(self.trait_of_item(def_id), Some(trait_id) if self.has_attr(trait_id, sym::const_trait))
}
/// Returns the `DefId` of the item within which the `impl Trait` is declared.
/// For type-alias-impl-trait this is the `type` alias.
/// For impl-trait-in-assoc-type this is the assoc type.
/// For return-position-impl-trait this is the function.
pub fn impl_trait_parent(self, mut def_id: LocalDefId) -> LocalDefId {
// Find the surrounding item (type alias or assoc type)
while let DefKind::OpaqueTy = self.def_kind(def_id) {
def_id = self.local_parent(def_id);
}
def_id
}
pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool {
if self.def_kind(def_id) != DefKind::AssocFn {
return false;