some nits, bless test

This commit is contained in:
Michael Goulet 2023-07-27 18:23:42 +00:00
parent 50d21091ee
commit 744e770939
3 changed files with 29 additions and 21 deletions

View File

@ -11,7 +11,10 @@ use std::iter;
pub fn provide(providers: &mut Providers) {
*providers = Providers {
assumed_wf_types,
assumed_wf_types_for_rpitit: |tcx, def_id| tcx.assumed_wf_types(def_id),
assumed_wf_types_for_rpitit: |tcx, def_id| {
assert!(tcx.is_impl_trait_in_trait(def_id.to_def_id()));
tcx.assumed_wf_types(def_id)
},
..*providers
};
}
@ -52,6 +55,15 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
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();
// 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 &(lifetime, new_early_bound_def_id) in
@ -81,14 +93,24 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
);
}
}
let a = tcx.fold_regions(
// 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(),
|re, _| {
if let Some(re) = mapping.get(&re) { *re } else { re }
|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(&region) {
*remapped_region
} else {
region
}
},
);
tcx.arena.alloc_from_iter(a)
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();

View File

@ -17,7 +17,6 @@ impl<'a, I: 'a + Iterable> Iterable for &'a I {
//~^ ERROR impl has stricter requirements than trait
fn iter(&self) -> impl 'a + Iterator<Item = I::Item<'a>> {
//~^ ERROR the type `&'a I` does not fulfill the required lifetime
(*self).iter()
}
}

View File

@ -12,19 +12,6 @@ help: copy the `where` clause predicates from the trait
LL | where Self: 'b;
| ~~~~~~~~~~~~~~
error[E0477]: the type `&'a I` does not fulfill the required lifetime
--> $DIR/bad-item-bound-within-rpitit.rs:19:23
|
LL | fn iter(&self) -> impl 'a + Iterator<Item = I::Item<'a>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: type must outlive the anonymous lifetime as defined here
--> $DIR/bad-item-bound-within-rpitit.rs:10:28
|
LL | fn iter(&self) -> impl '_ + Iterator<Item = Self::Item<'_>>;
| ^^
error: aborting due to previous error
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0276, E0477.
For more information about an error, try `rustc --explain E0276`.
For more information about this error, try `rustc --explain E0276`.