about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-04-19 15:18:00 -0400
committerMichael Goulet <michael@errs.io>2024-04-20 10:35:04 -0400
commitfa0428c9d0f336cf51748621543679736f04cce6 (patch)
tree6626c98281eaa3562074bac372652d1705b25412
parent584f183dc0e0ce8d981811ebbf67886c0cfef9e0 (diff)
downloadrust-fa0428c9d0f336cf51748621543679736f04cce6.tar.gz
rust-fa0428c9d0f336cf51748621543679736f04cce6.zip
Flip spans for precise capturing syntax not capturing a ty/ct param
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs29
-rw-r--r--compiler/rustc_hir_analysis/src/errors/precise_captures.rs6
-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.stderr6
-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.stderr13
7 files changed, 37 insertions, 28 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 36553591de8..8dfbcbfd76f 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,16 +592,22 @@ 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;
                     }
                 }
diff --git a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs
index 520bf1d9f40..d1b2205dd9a 100644
--- a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs
+++ b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs
@@ -6,9 +6,9 @@ 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,
 }
 
@@ -18,7 +18,7 @@ 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..8eeedc4db44 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
@@ -8,10 +8,12 @@ LL | #![feature(precise_capturing)]
    = 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
+  --> $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..4c04d177b06 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 all type parameters in scope
 }
 
 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..8cd873ea46d 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
@@ -8,21 +8,22 @@ LL | #![feature(precise_capturing)]
    = 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
+  --> $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
+  --> $DIR/forgot-to-capture-type.rs:8:17
    |
 LL | trait Foo {
-   | ^^^^^^^^^
-LL |
+   | --------- 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