about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSantiago Pastorino <spastorino@gmail.com>2022-10-18 14:05:17 -0300
committerSantiago Pastorino <spastorino@gmail.com>2022-10-19 16:49:39 -0300
commit49ce8a22b05d779da4ffc531a44380656d51404b (patch)
treef84e388b7699bac88463166c0242db04dc6acca0
parentfb5475887f8f3641aea994e1f8f8954d1290449a (diff)
downloadrust-49ce8a22b05d779da4ffc531a44380656d51404b.tar.gz
rust-49ce8a22b05d779da4ffc531a44380656d51404b.zip
Do anonymous lifetimes remapping correctly for nested rpits
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs27
-rw-r--r--src/test/ui/impl-trait/nested-rpit-with-anonymous-lifetimes.rs23
2 files changed, 34 insertions, 16 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index ea213385dc6..427b71722ab 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -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:
         //
@@ -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.
@@ -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(
@@ -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.
diff --git a/src/test/ui/impl-trait/nested-rpit-with-anonymous-lifetimes.rs b/src/test/ui/impl-trait/nested-rpit-with-anonymous-lifetimes.rs
new file mode 100644
index 00000000000..287a030cf87
--- /dev/null
+++ b/src/test/ui/impl-trait/nested-rpit-with-anonymous-lifetimes.rs
@@ -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() {}