about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl6
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs49
-rw-r--r--compiler/rustc_hir_analysis/src/errors/precise_captures.rs16
-rw-r--r--tests/ui/impl-trait/precise-capturing/capture-parent-arg.rs2
-rw-r--r--tests/ui/impl-trait/precise-capturing/capture-parent-arg.stderr7
-rw-r--r--tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.stderr8
-rw-r--r--tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs2
-rw-r--r--tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr17
8 files changed, 69 insertions, 38 deletions
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 0ff78ebff99..06b5ee299b8 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -351,7 +351,7 @@ hir_analysis_param_in_ty_of_assoc_const_binding =
         *[normal] the {$param_def_kind} `{$param_name}` is defined here
     }
 
-hir_analysis_param_not_captured = `impl Trait` must mention all {$kind} parameters in scope
+hir_analysis_param_not_captured = `impl Trait` must mention all {$kind} parameters in scope in `use<...>`
     .label = {$kind} parameter is implicitly captured by this `impl Trait`
     .note = currently, all {$kind} parameters are required to be mentioned in the precise captures list
 
@@ -405,6 +405,10 @@ hir_analysis_self_in_impl_self =
     `Self` is not valid in the self type of an impl block
     .note = replace `Self` with a different type
 
+hir_analysis_self_ty_not_captured = `impl Trait` must mention the `Self` type of the trait in `use<...>`
+    .label = `Self` type parameter is implicitly captured by this `impl Trait`
+    .note = currently, all type parameters are required to be mentioned in the precise captures list
+
 hir_analysis_simd_ffi_highly_experimental = use of SIMD type{$snip} in FFI is highly experimental and may result in invalid code
     .help = add `#![feature(simd_ffi)]` to the crate attributes to enable
 
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 36553591de8..a43a67d50d8 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -580,10 +580,11 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
 
             match param.kind {
                 ty::GenericParamDefKind::Lifetime => {
+                    let use_span = tcx.def_span(param.def_id);
+                    let opaque_span = tcx.def_span(opaque_def_id);
                     // Check if the lifetime param was captured but isn't named in the precise captures list.
                     if variances[param.index as usize] == ty::Invariant {
-                        let param_span = if let DefKind::OpaqueTy =
-                            tcx.def_kind(tcx.parent(param.def_id))
+                        if let DefKind::OpaqueTy = tcx.def_kind(tcx.parent(param.def_id))
                             && let ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
                             | ty::ReLateParam(ty::LateParamRegion {
                                 bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
@@ -591,26 +592,40 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
                             }) = *tcx
                                 .map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local())
                         {
-                            Some(tcx.def_span(def_id))
+                            tcx.dcx().emit_err(errors::LifetimeNotCaptured {
+                                opaque_span,
+                                use_span,
+                                param_span: tcx.def_span(def_id),
+                            });
                         } else {
-                            None
-                        };
-                        // FIXME(precise_capturing): Structured suggestion for this would be useful
-                        tcx.dcx().emit_err(errors::LifetimeNotCaptured {
-                            use_span: tcx.def_span(param.def_id),
-                            param_span,
-                            opaque_span: tcx.def_span(opaque_def_id),
-                        });
+                            // If the `use_span` is actually just the param itself, then we must
+                            // have not duplicated the lifetime but captured the original.
+                            // The "effective" `use_span` will be the span of the opaque itself,
+                            // and the param span will be the def span of the param.
+                            tcx.dcx().emit_err(errors::LifetimeNotCaptured {
+                                opaque_span,
+                                use_span: opaque_span,
+                                param_span: use_span,
+                            });
+                        }
                         continue;
                     }
                 }
                 ty::GenericParamDefKind::Type { .. } => {
-                    // FIXME(precise_capturing): Structured suggestion for this would be useful
-                    tcx.dcx().emit_err(errors::ParamNotCaptured {
-                        param_span: tcx.def_span(param.def_id),
-                        opaque_span: tcx.def_span(opaque_def_id),
-                        kind: "type",
-                    });
+                    if matches!(tcx.def_kind(param.def_id), DefKind::Trait | DefKind::TraitAlias) {
+                        // FIXME(precise_capturing): Structured suggestion for this would be useful
+                        tcx.dcx().emit_err(errors::SelfTyNotCaptured {
+                            trait_span: tcx.def_span(param.def_id),
+                            opaque_span: tcx.def_span(opaque_def_id),
+                        });
+                    } else {
+                        // FIXME(precise_capturing): Structured suggestion for this would be useful
+                        tcx.dcx().emit_err(errors::ParamNotCaptured {
+                            param_span: tcx.def_span(param.def_id),
+                            opaque_span: tcx.def_span(opaque_def_id),
+                            kind: "type",
+                        });
+                    }
                 }
                 ty::GenericParamDefKind::Const { .. } => {
                     // FIXME(precise_capturing): Structured suggestion for this would be useful
diff --git a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs
index 520bf1d9f40..8a9b5fe6369 100644
--- a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs
+++ b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs
@@ -6,19 +6,29 @@ use rustc_span::{Span, Symbol};
 #[note]
 pub struct ParamNotCaptured {
     #[primary_span]
-    pub param_span: Span,
-    #[label]
     pub opaque_span: Span,
+    #[label]
+    pub param_span: Span,
     pub kind: &'static str,
 }
 
 #[derive(Diagnostic)]
+#[diag(hir_analysis_self_ty_not_captured)]
+#[note]
+pub struct SelfTyNotCaptured {
+    #[primary_span]
+    pub opaque_span: Span,
+    #[label]
+    pub trait_span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(hir_analysis_lifetime_not_captured)]
 pub struct LifetimeNotCaptured {
     #[primary_span]
     pub use_span: Span,
     #[label(hir_analysis_param_label)]
-    pub param_span: Option<Span>,
+    pub param_span: Span,
     #[label]
     pub opaque_span: Span,
 }
diff --git a/tests/ui/impl-trait/precise-capturing/capture-parent-arg.rs b/tests/ui/impl-trait/precise-capturing/capture-parent-arg.rs
index f880bb038d5..35b28d0e6fb 100644
--- a/tests/ui/impl-trait/precise-capturing/capture-parent-arg.rs
+++ b/tests/ui/impl-trait/precise-capturing/capture-parent-arg.rs
@@ -31,8 +31,8 @@ impl<'a> W<'a> {
 
 // But also make sure that we error here...
 impl<'a> W<'a> {
-//~^ ERROR `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
     fn bad2() -> impl use<> Into<<Self as Tr>::Assoc> {}
+    //~^ ERROR `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/capture-parent-arg.stderr b/tests/ui/impl-trait/precise-capturing/capture-parent-arg.stderr
index 85790d57163..13aaa999707 100644
--- a/tests/ui/impl-trait/precise-capturing/capture-parent-arg.stderr
+++ b/tests/ui/impl-trait/precise-capturing/capture-parent-arg.stderr
@@ -16,13 +16,12 @@ LL |     fn bad1() -> impl use<> Into<<W<'a> as Tr>::Assoc> {}
    |                  -------------------^^---------------- lifetime captured due to being mentioned in the bounds of the `impl Trait`
 
 error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
-  --> $DIR/capture-parent-arg.rs:33:6
+  --> $DIR/capture-parent-arg.rs:34:18
    |
 LL | impl<'a> W<'a> {
-   |      ^^
-LL |
+   |      -- this lifetime parameter is captured
 LL |     fn bad2() -> impl use<> Into<<Self as Tr>::Assoc> {}
-   |                  ------------------------------------ lifetime captured due to being mentioned in the bounds of the `impl Trait`
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime captured due to being mentioned in the bounds of the `impl Trait`
 
 error: aborting due to 2 previous errors; 1 warning emitted
 
diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.stderr b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.stderr
index 9c99f2b711e..3f78e7c56b6 100644
--- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.stderr
+++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.stderr
@@ -7,11 +7,13 @@ LL | #![feature(precise_capturing)]
    = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: `impl Trait` must mention all const parameters in scope
-  --> $DIR/forgot-to-capture-const.rs:4:13
+error: `impl Trait` must mention all const parameters in scope in `use<...>`
+  --> $DIR/forgot-to-capture-const.rs:4:34
    |
 LL | fn constant<const C: usize>() -> impl use<> Sized {}
-   |             ^^^^^^^^^^^^^^       ---------------- const parameter is implicitly captured by this `impl Trait`
+   |             --------------       ^^^^^^^^^^^^^^^^
+   |             |
+   |             const parameter is implicitly captured by this `impl Trait`
    |
    = note: currently, all const parameters are required to be mentioned in the precise captures list
 
diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs
index 6eaff01183d..d359ea5e26d 100644
--- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs
+++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs
@@ -5,8 +5,8 @@ fn type_param<T>() -> impl use<> Sized {}
 //~^ ERROR `impl Trait` must mention all type parameters in scope
 
 trait Foo {
-//~^ ERROR `impl Trait` must mention all type parameters in scope
     fn bar() -> impl use<> Sized;
+    //~^ ERROR `impl Trait` must mention the `Self` type of the trait
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr
index a8eb4547dcd..26994d0bdbf 100644
--- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr
+++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr
@@ -7,22 +7,23 @@ LL | #![feature(precise_capturing)]
    = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: `impl Trait` must mention all type parameters in scope
-  --> $DIR/forgot-to-capture-type.rs:4:15
+error: `impl Trait` must mention all type parameters in scope in `use<...>`
+  --> $DIR/forgot-to-capture-type.rs:4:23
    |
 LL | fn type_param<T>() -> impl use<> Sized {}
-   |               ^       ---------------- type parameter is implicitly captured by this `impl Trait`
+   |               -       ^^^^^^^^^^^^^^^^
+   |               |
+   |               type parameter is implicitly captured by this `impl Trait`
    |
    = note: currently, all type parameters are required to be mentioned in the precise captures list
 
-error: `impl Trait` must mention all type parameters in scope
-  --> $DIR/forgot-to-capture-type.rs:7:1
+error: `impl Trait` must mention the `Self` type of the trait in `use<...>`
+  --> $DIR/forgot-to-capture-type.rs:8:17
    |
 LL | trait Foo {
-   | ^^^^^^^^^
-LL |
+   | --------- `Self` type parameter is implicitly captured by this `impl Trait`
 LL |     fn bar() -> impl use<> Sized;
-   |                 ---------------- type parameter is implicitly captured by this `impl Trait`
+   |                 ^^^^^^^^^^^^^^^^
    |
    = note: currently, all type parameters are required to be mentioned in the precise captures list