diff options
| author | bors <bors@rust-lang.org> | 2023-08-08 13:03:10 +0000 | 
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-08-08 13:03:10 +0000 | 
| commit | bf62436bce9668118bc4d5f7795f08745d478ac0 (patch) | |
| tree | c12b2e7e4b87f02f2dddfab50e2feac6dd2bf2f4 /compiler/rustc_ty_utils/src/implied_bounds.rs | |
| parent | 617821ab32b7a7563f561812385e2fba7b1d2981 (diff) | |
| parent | 0adf7048d23649d561bb121d7e1ab00b4c0269b0 (diff) | |
| download | rust-bf62436bce9668118bc4d5f7795f08745d478ac0.tar.gz rust-bf62436bce9668118bc4d5f7795f08745d478ac0.zip | |
Auto merge of #114602 - compiler-errors:rpit-outlives-sadness, r=oli-obk
Map RPIT duplicated lifetimes back to fn captured lifetimes Use the [`lifetime_mapping`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.OpaqueTy.html#structfield.lifetime_mapping) to map an RPIT's captured lifetimes back to the early- or late-bound lifetimes from its parent function. We may be going thru several layers of mapping, since opaques can be nested, so we introduce `TyCtxt::map_rpit_lifetime_to_fn_lifetime` to loop through several opaques worth of mapping, and handle turning it into a `ty::Region` as well. We can then use this instead of the identity substs for RPITs in `check_opaque_meets_bounds` to address #114285. We can then also use `map_rpit_lifetime_to_fn_lifetime` to properly install bidirectional-outlives predicates for both RPITs and RPITITs. This addresses #114601. I based this on #114574, but I don't actually know how much of that PR we still need, so some code may be redundant now... :shrug: --- Fixes #114597 Fixes #114579 Fixes #114285 Also fixes #114601, since it turns out we had other bugs with RPITITs and their duplicated lifetime params :sweat_smile:. Supersedes #114574 r? `@oli-obk`
Diffstat (limited to 'compiler/rustc_ty_utils/src/implied_bounds.rs')
| -rw-r--r-- | compiler/rustc_ty_utils/src/implied_bounds.rs | 35 | 
1 files changed, 13 insertions, 22 deletions
| diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index aa49a5561d1..436f10a4f7b 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -2,7 +2,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; -use rustc_middle::middle::resolve_bound_vars as rbv; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; @@ -52,9 +51,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' 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, opaque_def_id } => { - let hir::OpaqueTy { lifetime_mapping, .. } = - *tcx.hir().expect_item(opaque_def_id.expect_local()).expect_opaque_ty(); + 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). @@ -66,28 +63,22 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' // predicates we insert in the `explicit_predicates_of` query for RPITITs. let mut mapping = FxHashMap::default(); let generics = tcx.generics_of(def_id); - for &(lifetime, new_early_bound_def_id) in - lifetime_mapping.expect("expected lifetime mapping for RPITIT") - { - if let Some(rbv::ResolvedArg::LateBound(_, _, def_id)) = - tcx.named_bound_var(lifetime.hir_id) - { - let name = tcx.hir().name(lifetime.hir_id); - let index = generics - .param_def_id_to_index(tcx, new_early_bound_def_id.to_def_id()) - .unwrap(); + + // 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( - ty::Region::new_free( - tcx, - fn_def_id, - ty::BoundRegionKind::BrNamed(def_id, name), - ), + orig_lt, ty::Region::new_early_bound( tcx, ty::EarlyBoundRegion { - def_id: new_early_bound_def_id.to_def_id(), - index, - name, + def_id: param.def_id, + index: param.index, + name: param.name, }, ), ); | 
