Skip to content

Commit

Permalink
Do anonymous lifetimes remapping correctly for nested rpits
Browse files Browse the repository at this point in the history
  • Loading branch information
spastorino committed Oct 19, 2022
1 parent fb54758 commit 49ce8a2
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 16 deletions.
27 changes: 11 additions & 16 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -540,9 +540,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {

/// Get the previously recorded `to` local def id given the `from` local def id, obtained using
/// `generics_def_id_map` field.
fn get_remapped_def_id(&self, mut local_def_id: LocalDefId) -> LocalDefId {
fn get_remapped_def_id(&self, local_def_id: LocalDefId) -> LocalDefId {
// `generics_def_id_map` is a stack of mappings. As we go deeper in impl traits nesting we
// push new mappings so we need to try first the latest mappings, hence `iter().rev()`.
// push new mappings, so we first need to get the latest (innermost) mappings, hence `iter().rev()`.
//
// Consider:
//
Expand All @@ -552,18 +552,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
//
// `[[fn#'b -> impl_trait#'b], [fn#'b -> impl_sized#'b]]`
//
// for the opaque type generated on `impl Sized + 'b`, We want the result to be:
// impl_sized#'b, so iterating forward is the wrong thing to do.
for map in self.generics_def_id_map.iter().rev() {
if let Some(r) = map.get(&local_def_id) {
debug!("def_id_remapper: remapping from `{local_def_id:?}` to `{r:?}`");
local_def_id = *r;
} else {
debug!("def_id_remapper: no remapping for `{local_def_id:?}` found in map");
}
}

local_def_id
// for the opaque type generated on `impl Sized + 'b`, we want the result to be: impl_sized#'b.
// So, if we were trying to find first from the start (outermost) would give the wrong result, impl_trait#'b.
self.generics_def_id_map
.iter()
.rev()
.find_map(|map| map.get(&local_def_id).map(|local_def_id| *local_def_id))
.unwrap_or(local_def_id)
}

/// Freshen the `LoweringContext` and ready it to lower a nested item.
Expand Down Expand Up @@ -1641,7 +1636,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {

LifetimeRes::Fresh { param, binder: _ } => {
debug_assert_eq!(lifetime.ident.name, kw::UnderscoreLifetime);
if let Some(old_def_id) = self.opt_local_def_id(param) && remapping.get(&old_def_id).is_none() {
if let Some(old_def_id) = self.orig_opt_local_def_id(param) && remapping.get(&old_def_id).is_none() {
let node_id = self.next_node_id();

let new_def_id = self.create_def(
Expand Down Expand Up @@ -1886,7 +1881,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let extra_lifetime_params = self.resolver.take_extra_lifetime_params(opaque_ty_node_id);
debug!(?extra_lifetime_params);
for (ident, outer_node_id, outer_res) in extra_lifetime_params {
let outer_def_id = self.local_def_id(outer_node_id);
let outer_def_id = self.orig_local_def_id(outer_node_id);
let inner_node_id = self.next_node_id();

// Add a definition for the in scope lifetime def.
Expand Down
23 changes: 23 additions & 0 deletions src/test/ui/impl-trait/nested-rpit-with-anonymous-lifetimes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// check-pass

pub struct VecNumber<'s> {
pub vec_number: Vec<Number<'s>>,
pub auxiliary_object: &'s Vec<usize>,
}

pub struct Number<'s> {
pub number: &'s usize,
}

impl<'s> VecNumber<'s> {
pub fn vec_number_iterable_per_item_in_auxiliary_object(
&self,
) -> impl Iterator<Item = (&'s usize, impl Iterator<Item = &Number<'s>>)> {
self.auxiliary_object.iter().map(move |n| {
let iter_number = self.vec_number.iter();
(n, iter_number)
})
}
}

fn main() {}

0 comments on commit 49ce8a2

Please sign in to comment.