From 36076ecdc726c4e1104e70df2d142f39501a4f48 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 29 Sep 2024 13:49:32 -0400 Subject: [PATCH] Clarify implicit captures for RPITIT --- compiler/rustc_hir_analysis/messages.ftl | 3 +++ .../rustc_hir_analysis/src/check/check.rs | 25 ++++++++++++------- .../src/errors/precise_captures.rs | 9 +++++++ .../precise-capturing/rpitit.stderr | 4 +-- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index c73826c489f9..a80dc87c6224 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -259,6 +259,9 @@ hir_analysis_late_bound_lifetime_in_apit = `impl Trait` can only mention lifetim hir_analysis_late_bound_type_in_apit = `impl Trait` can only mention type parameters from an fn or impl .label = type parameter declared here +hir_analysis_lifetime_implicitly_captured = `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list + .param_label = all lifetime parameters originating from a trait are captured implicitly + hir_analysis_lifetime_must_be_first = lifetime parameter `{$name}` must be listed before non-lifetime parameters .label = move the lifetime before this parameter diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index eb62ff86c717..d0063b449f89 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -589,15 +589,22 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe param_span: tcx.def_span(def_id), }); } else { - // 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, - }); + if tcx.def_kind(tcx.parent(param.def_id)) == DefKind::Trait { + tcx.dcx().emit_err(errors::LifetimeImplicitlyCaptured { + opaque_span, + param_span: tcx.def_span(param.def_id), + }); + } else { + // 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 b6cffb90805b..8a83866b7fa4 100644 --- a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs +++ b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs @@ -34,6 +34,15 @@ pub(crate) struct LifetimeNotCaptured { pub opaque_span: Span, } +#[derive(Diagnostic)] +#[diag(hir_analysis_lifetime_implicitly_captured)] +pub(crate) struct LifetimeImplicitlyCaptured { + #[primary_span] + pub opaque_span: Span, + #[label(hir_analysis_param_label)] + pub param_span: Span, +} + #[derive(Diagnostic)] #[diag(hir_analysis_bad_precise_capture)] pub(crate) struct BadPreciseCapture { diff --git a/tests/ui/impl-trait/precise-capturing/rpitit.stderr b/tests/ui/impl-trait/precise-capturing/rpitit.stderr index 8c219bb04a27..498eae54a1c6 100644 --- a/tests/ui/impl-trait/precise-capturing/rpitit.stderr +++ b/tests/ui/impl-trait/precise-capturing/rpitit.stderr @@ -2,9 +2,9 @@ error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use --> $DIR/rpitit.rs:11:19 | LL | trait TraitLt<'a: 'a> { - | -- this lifetime parameter is captured + | -- all lifetime parameters originating from a trait are captured implicitly LL | fn hello() -> impl Sized + use; - | ^^^^^^^^^^^^^^^^^^^^^^ lifetime captured due to being mentioned in the bounds of the `impl Trait` + | ^^^^^^^^^^^^^^^^^^^^^^ error: lifetime may not live long enough --> $DIR/rpitit.rs:15:5