Clarify implicit captures for RPITIT

This commit is contained in:
Michael Goulet 2024-09-29 13:49:32 -04:00 committed by Jubilee Young
parent a7dc98733d
commit 36076ecdc7
4 changed files with 30 additions and 11 deletions

View File

@ -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 hir_analysis_late_bound_type_in_apit = `impl Trait` can only mention type parameters from an fn or impl
.label = type parameter declared here .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 hir_analysis_lifetime_must_be_first = lifetime parameter `{$name}` must be listed before non-lifetime parameters
.label = move the lifetime before this parameter .label = move the lifetime before this parameter

View File

@ -589,15 +589,22 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
param_span: tcx.def_span(def_id), param_span: tcx.def_span(def_id),
}); });
} else { } else {
// If the `use_span` is actually just the param itself, then we must if tcx.def_kind(tcx.parent(param.def_id)) == DefKind::Trait {
// have not duplicated the lifetime but captured the original. tcx.dcx().emit_err(errors::LifetimeImplicitlyCaptured {
// The "effective" `use_span` will be the span of the opaque itself, opaque_span,
// and the param span will be the def span of the param. param_span: tcx.def_span(param.def_id),
tcx.dcx().emit_err(errors::LifetimeNotCaptured { });
opaque_span, } else {
use_span: opaque_span, // If the `use_span` is actually just the param itself, then we must
param_span: use_span, // 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; continue;
} }

View File

@ -34,6 +34,15 @@ pub(crate) struct LifetimeNotCaptured {
pub opaque_span: Span, 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)] #[derive(Diagnostic)]
#[diag(hir_analysis_bad_precise_capture)] #[diag(hir_analysis_bad_precise_capture)]
pub(crate) struct BadPreciseCapture { pub(crate) struct BadPreciseCapture {

View File

@ -2,9 +2,9 @@ error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use
--> $DIR/rpitit.rs:11:19 --> $DIR/rpitit.rs:11:19
| |
LL | trait TraitLt<'a: 'a> { 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<Self>; LL | fn hello() -> impl Sized + use<Self>;
| ^^^^^^^^^^^^^^^^^^^^^^ lifetime captured due to being mentioned in the bounds of the `impl Trait` | ^^^^^^^^^^^^^^^^^^^^^^
error: lifetime may not live long enough error: lifetime may not live long enough
--> $DIR/rpitit.rs:15:5 --> $DIR/rpitit.rs:15:5