about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs15
-rw-r--r--compiler/rustc_middle/src/ty/generics.rs8
-rw-r--r--tests/crashes/129850.rs9
-rw-r--r--tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.rs16
-rw-r--r--tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.stderr42
5 files changed, 73 insertions, 17 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 388e02b36e0..cc7a0dff34e 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -726,7 +726,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
                     num_trait_args,
                     num_impl_args,
                     def_id,
-                    impl_def_id: impl_m.container_id(tcx),
+                    impl_m_def_id: impl_m.def_id,
                     ty,
                     return_span,
                 }) {
@@ -844,12 +844,18 @@ where
 
 struct RemapHiddenTyRegions<'tcx> {
     tcx: TyCtxt<'tcx>,
+    /// Map from early/late params of the impl to identity regions of the RPITIT (GAT)
+    /// in the trait.
     map: FxIndexMap<ty::Region<'tcx>, ty::Region<'tcx>>,
     num_trait_args: usize,
     num_impl_args: usize,
+    /// Def id of the RPITIT (GAT) in the *trait*.
     def_id: DefId,
-    impl_def_id: DefId,
+    /// Def id of the impl method which owns the opaque hidden type we're remapping.
+    impl_m_def_id: DefId,
+    /// The hidden type we're remapping. Useful for diagnostics.
     ty: Ty<'tcx>,
+    /// Span of the return type. Useful for diagnostics.
     return_span: Span,
 }
 
@@ -885,8 +891,7 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
             ty::ReLateParam(_) => {}
             // Remap early-bound regions as long as they don't come from the `impl` itself,
             // in which case we don't really need to renumber them.
-            ty::ReEarlyParam(ebr)
-                if ebr.index >= self.tcx.generics_of(self.impl_def_id).count() as u32 => {}
+            ty::ReEarlyParam(ebr) if ebr.index as usize >= self.num_impl_args => {}
             _ => return Ok(region),
         }
 
@@ -899,7 +904,7 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
                 );
             }
         } else {
-            let guar = match region.opt_param_def_id(self.tcx, self.tcx.parent(self.def_id)) {
+            let guar = match region.opt_param_def_id(self.tcx, self.impl_m_def_id) {
                 Some(def_id) => {
                     let return_span = if let ty::Alias(ty::Opaque, opaque_ty) = self.ty.kind() {
                         self.tcx.def_span(opaque_ty.def_id)
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index bbc696e0f08..5f9a89c3a5b 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -255,7 +255,9 @@ impl<'tcx> Generics {
         let param = self.param_at(param.index as usize, tcx);
         match param.kind {
             GenericParamDefKind::Lifetime => param,
-            _ => bug!("expected lifetime parameter, but found another generic parameter"),
+            _ => {
+                bug!("expected lifetime parameter, but found another generic parameter: {param:#?}")
+            }
         }
     }
 
@@ -264,7 +266,7 @@ impl<'tcx> Generics {
         let param = self.param_at(param.index as usize, tcx);
         match param.kind {
             GenericParamDefKind::Type { .. } => param,
-            _ => bug!("expected type parameter, but found another generic parameter"),
+            _ => bug!("expected type parameter, but found another generic parameter: {param:#?}"),
         }
     }
 
@@ -273,7 +275,7 @@ impl<'tcx> Generics {
         let param = self.param_at(param.index as usize, tcx);
         match param.kind {
             GenericParamDefKind::Const { .. } => param,
-            _ => bug!("expected const parameter, but found another generic parameter"),
+            _ => bug!("expected const parameter, but found another generic parameter: {param:#?}"),
         }
     }
 
diff --git a/tests/crashes/129850.rs b/tests/crashes/129850.rs
deleted file mode 100644
index 9c04805587a..00000000000
--- a/tests/crashes/129850.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@ known-bug: rust-lang/rust#129850
-
-pub trait Foo2 {
-    fn bar<'a: 'a>(&'a mut self) -> impl Sized + use<'static>;
-}
-
-impl Foo2 for () {
-    fn bar<'a: 'a>(&'a mut self) -> impl Sized + 'a {}
-}
diff --git a/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.rs b/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.rs
new file mode 100644
index 00000000000..71a91fe319e
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.rs
@@ -0,0 +1,16 @@
+// Make sure we don't ICE when an RPITIT captures more method args than the
+// trait definition, which is not allowed. Due to the default lifetime capture
+// rules of RPITITs, this is only doable if we use precise capturing.
+
+pub trait Foo {
+    fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
+    //~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
+}
+
+impl Foo for () {
+    fn bar<'im: 'im>(&'im mut self) -> impl Sized + 'im {}
+    //~^ ERROR return type captures more lifetimes than trait definition
+    //~| WARN impl trait in impl method signature does not match trait method signature
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.stderr b/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.stderr
new file mode 100644
index 00000000000..339e2e6335e
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.stderr
@@ -0,0 +1,42 @@
+error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
+  --> $DIR/rpitit-captures-more-method-lifetimes.rs:6:53
+   |
+LL |     fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
+   |                                                     ^^^^^^^^^
+   |
+   = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
+
+error: return type captures more lifetimes than trait definition
+  --> $DIR/rpitit-captures-more-method-lifetimes.rs:11:40
+   |
+LL |     fn bar<'im: 'im>(&'im mut self) -> impl Sized + 'im {}
+   |            ---                         ^^^^^^^^^^^^^^^^
+   |            |
+   |            this lifetime was captured
+   |
+note: hidden type must only reference lifetimes captured by this impl trait
+  --> $DIR/rpitit-captures-more-method-lifetimes.rs:6:40
+   |
+LL |     fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^
+   = note: hidden type inferred to be `impl Sized + 'im`
+
+warning: impl trait in impl method signature does not match trait method signature
+  --> $DIR/rpitit-captures-more-method-lifetimes.rs:11:40
+   |
+LL |     fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
+   |                                        ---------------------- return type from trait method defined here
+...
+LL |     fn bar<'im: 'im>(&'im mut self) -> impl Sized + 'im {}
+   |                                        ^^^^^^^^^^^^^^^^
+   |
+   = note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
+   = note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
+   = note: `#[warn(refining_impl_trait_reachable)]` on by default
+help: replace the return type so that it matches the trait
+   |
+LL |     fn bar<'im: 'im>(&'im mut self) -> impl Sized {}
+   |                                        ~~~~~~~~~~
+
+error: aborting due to 2 previous errors; 1 warning emitted
+