about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs9
-rw-r--r--tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs13
-rw-r--r--tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.stderr32
3 files changed, 53 insertions, 1 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 9483439ae4e..6fd0535a28b 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -571,17 +571,23 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
             // We list scopes outwards, this causes us to see lifetime parameters in reverse
             // declaration order. In order to make it consistent with what `generics_of` might
             // give, we will reverse the IndexMap after early captures.
+            let mut late_depth = 0;
             let mut scope = self.scope;
             let mut opaque_capture_scopes = vec![(opaque.def_id, &captures)];
             loop {
                 match *scope {
-                    Scope::Binder { ref bound_vars, s, .. } => {
+                    Scope::Binder { ref bound_vars, scope_type, s, .. } => {
                         for (&original_lifetime, &def) in bound_vars.iter().rev() {
                             if let DefKind::LifetimeParam = self.tcx.def_kind(original_lifetime) {
+                                let def = def.shifted(late_depth);
                                 let ident = lifetime_ident(original_lifetime);
                                 self.remap_opaque_captures(&opaque_capture_scopes, def, ident);
                             }
                         }
+                        match scope_type {
+                            BinderScopeType::Normal => late_depth += 1,
+                            BinderScopeType::Concatenating => {}
+                        }
                         scope = s;
                     }
 
@@ -602,6 +608,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
 
                     Scope::Opaque { captures, def_id, s } => {
                         opaque_capture_scopes.push((def_id, captures));
+                        late_depth = 0;
                         scope = s;
                     }
 
diff --git a/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs b/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs
new file mode 100644
index 00000000000..9d1bb22434c
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs
@@ -0,0 +1,13 @@
+// Test for issue #132429
+//@compile-flags: -Zunstable-options --edition=2024
+
+trait ThreeCellFragment {
+    fn ext_cells<'a>(
+        &'a self,
+    ) -> dyn core::future::Future<Output = impl IntoIterator<Item = u32>> + 'a {
+        //~^ ERROR mismatched types
+        //~| ERROR return type cannot have an unboxed trait object
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.stderr b/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.stderr
new file mode 100644
index 00000000000..f771b802af9
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.stderr
@@ -0,0 +1,32 @@
+error[E0308]: mismatched types
+  --> $DIR/late-bound-in-object-assocty.rs:7:80
+   |
+LL |       ) -> dyn core::future::Future<Output = impl IntoIterator<Item = u32>> + 'a {
+   |  ________________________________________________________________________________^
+LL | |
+LL | |
+LL | |     }
+   | |_____^ expected `dyn Future`, found `()`
+   |
+   = note: expected trait object `(dyn Future<Output = _> + 'a)`
+                 found unit type `()`
+
+error[E0746]: return type cannot have an unboxed trait object
+  --> $DIR/late-bound-in-object-assocty.rs:7:10
+   |
+LL |     ) -> dyn core::future::Future<Output = impl IntoIterator<Item = u32>> + 'a {
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+help: consider returning an `impl Trait` instead of a `dyn Trait`
+   |
+LL |     ) -> impl core::future::Future<Output = impl IntoIterator<Item = u32>> + 'a {
+   |          ~~~~
+help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
+   |
+LL |     ) -> Box<dyn core::future::Future<Output = impl IntoIterator<Item = u32>> + 'a> {
+   |          ++++                                                                     +
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0746.
+For more information about an error, try `rustc --explain E0308`.