From fa0428c9d0f336cf51748621543679736f04cce6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 19 Apr 2024 15:18:00 -0400 Subject: [PATCH] Flip spans for precise capturing syntax not capturing a ty/ct param --- .../rustc_hir_analysis/src/check/check.rs | 29 ++++++++++++------- .../src/errors/precise_captures.rs | 6 ++-- .../precise-capturing/capture-parent-arg.rs | 2 +- .../capture-parent-arg.stderr | 7 ++--- .../forgot-to-capture-const.stderr | 6 ++-- .../forgot-to-capture-type.rs | 2 +- .../forgot-to-capture-type.stderr | 13 +++++---- 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 @@ #[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, + 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 @@ fn bad1() -> impl use<> Into< as Tr>::Assoc> {} // 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<::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< 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<::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() -> 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() -> 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() -> 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