From 45d44650280951c22ba625d0000d36216babb397 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 1 Nov 2024 17:03:17 +0000 Subject: [PATCH 1/3] Account for late-bound depth when capturing all opaque lifetimes. --- .../src/collect/resolve_bound_vars.rs | 9 +++++- .../in-trait/late-bound-in-object-assocty.rs | 13 ++++++++ .../late-bound-in-object-assocty.stderr | 32 +++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs create mode 100644 tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.stderr 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 9483439ae4e8f..6fd0535a28b01 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 0000000000000..9d1bb22434c4f --- /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> + '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 0000000000000..f771b802af970 --- /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> + 'a { + | ________________________________________________________________________________^ +LL | | +LL | | +LL | | } + | |_____^ expected `dyn Future`, found `()` + | + = note: expected trait object `(dyn Future + '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> + '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> + 'a { + | ~~~~ +help: alternatively, box the return type, and wrap all of the returned values in `Box::new` + | +LL | ) -> Box> + '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`. From a7f609504c92c9912b61025ae26a5404d3ee4311 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 1 Nov 2024 17:42:14 +0000 Subject: [PATCH 2/3] Skip late-bound lifetimes when crossing an AnonConst. --- .../src/collect/resolve_bound_vars.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 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 6fd0535a28b01..dc3ef9952f05a 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -573,11 +573,17 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { // give, we will reverse the IndexMap after early captures. let mut late_depth = 0; let mut scope = self.scope; + let mut crossed_late_boundary = None; let mut opaque_capture_scopes = vec![(opaque.def_id, &captures)]; loop { match *scope { Scope::Binder { ref bound_vars, scope_type, s, .. } => { for (&original_lifetime, &def) in bound_vars.iter().rev() { + if let ResolvedArg::LateBound(..) = def + && crossed_late_boundary.is_some() + { + continue; + } if let DefKind::LifetimeParam = self.tcx.def_kind(original_lifetime) { let def = def.shifted(late_depth); let ident = lifetime_ident(original_lifetime); @@ -618,8 +624,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { Scope::ObjectLifetimeDefault { s, .. } | Scope::Supertrait { s, .. } - | Scope::TraitRefBoundary { s, .. } - | Scope::LateBoundary { s, .. } => { + | Scope::TraitRefBoundary { s, .. } => { + scope = s; + } + + Scope::LateBoundary { s, what, .. } => { + crossed_late_boundary = Some(what); scope = s; } } From e2a50de5f4cda9958f910ee86a05c46e81767a32 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 1 Nov 2024 18:00:36 +0000 Subject: [PATCH 3/3] Use more minimized test. --- .../in-trait/late-bound-in-object-assocty.rs | 12 +++---- .../late-bound-in-object-assocty.stderr | 32 ------------------- 2 files changed, 6 insertions(+), 38 deletions(-) delete mode 100644 tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.stderr 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 index 9d1bb22434c4f..83466535e13c6 100644 --- 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 @@ -1,12 +1,12 @@ // Test for issue #132429 //@compile-flags: -Zunstable-options --edition=2024 +//@check-pass -trait ThreeCellFragment { - fn ext_cells<'a>( - &'a self, - ) -> dyn core::future::Future> + 'a { - //~^ ERROR mismatched types - //~| ERROR return type cannot have an unboxed trait object +use std::future::Future; + +trait Test { + fn foo<'a>(&'a self) -> Box>> { + Box::new(async { [] }) } } 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 deleted file mode 100644 index f771b802af970..0000000000000 --- a/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.stderr +++ /dev/null @@ -1,32 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/late-bound-in-object-assocty.rs:7:80 - | -LL | ) -> dyn core::future::Future> + 'a { - | ________________________________________________________________________________^ -LL | | -LL | | -LL | | } - | |_____^ expected `dyn Future`, found `()` - | - = note: expected trait object `(dyn Future + '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> + '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> + 'a { - | ~~~~ -help: alternatively, box the return type, and wrap all of the returned values in `Box::new` - | -LL | ) -> Box> + '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`.