Skip to content

Commit 2304da0

Browse files
Clarify implicit captures for RPITIT
1 parent 82e5389 commit 2304da0

File tree

4 files changed

+30
-11
lines changed

4 files changed

+30
-11
lines changed

compiler/rustc_hir_analysis/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,9 @@ hir_analysis_late_bound_lifetime_in_apit = `impl Trait` can only mention lifetim
259259
hir_analysis_late_bound_type_in_apit = `impl Trait` can only mention type parameters from an fn or impl
260260
.label = type parameter declared here
261261
262+
hir_analysis_lifetime_implicitly_captured = `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
263+
.param_label = all lifetime parameters originating from a trait are captured implicitly
264+
262265
hir_analysis_lifetime_must_be_first = lifetime parameter `{$name}` must be listed before non-lifetime parameters
263266
.label = move the lifetime before this parameter
264267

compiler/rustc_hir_analysis/src/check/check.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -593,15 +593,22 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
593593
param_span: tcx.def_span(def_id),
594594
});
595595
} else {
596-
// If the `use_span` is actually just the param itself, then we must
597-
// have not duplicated the lifetime but captured the original.
598-
// The "effective" `use_span` will be the span of the opaque itself,
599-
// and the param span will be the def span of the param.
600-
tcx.dcx().emit_err(errors::LifetimeNotCaptured {
601-
opaque_span,
602-
use_span: opaque_span,
603-
param_span: use_span,
604-
});
596+
if tcx.def_kind(tcx.parent(param.def_id)) == DefKind::Trait {
597+
tcx.dcx().emit_err(errors::LifetimeImplicitlyCaptured {
598+
opaque_span,
599+
param_span: tcx.def_span(param.def_id),
600+
});
601+
} else {
602+
// If the `use_span` is actually just the param itself, then we must
603+
// have not duplicated the lifetime but captured the original.
604+
// The "effective" `use_span` will be the span of the opaque itself,
605+
// and the param span will be the def span of the param.
606+
tcx.dcx().emit_err(errors::LifetimeNotCaptured {
607+
opaque_span,
608+
use_span: opaque_span,
609+
param_span: use_span,
610+
});
611+
}
605612
}
606613
continue;
607614
}

compiler/rustc_hir_analysis/src/errors/precise_captures.rs

+9
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ pub(crate) struct LifetimeNotCaptured {
3434
pub opaque_span: Span,
3535
}
3636

37+
#[derive(Diagnostic)]
38+
#[diag(hir_analysis_lifetime_implicitly_captured)]
39+
pub(crate) struct LifetimeImplicitlyCaptured {
40+
#[primary_span]
41+
pub opaque_span: Span,
42+
#[label(hir_analysis_param_label)]
43+
pub param_span: Span,
44+
}
45+
3746
#[derive(Diagnostic)]
3847
#[diag(hir_analysis_bad_precise_capture)]
3948
pub(crate) struct BadPreciseCapture {

tests/ui/impl-trait/precise-capturing/rpitit.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use
22
--> $DIR/rpitit.rs:11:19
33
|
44
LL | trait TraitLt<'a: 'a> {
5-
| -- this lifetime parameter is captured
5+
| -- all lifetime parameters originating from a trait are captured implicitly
66
LL | fn hello() -> impl Sized + use<Self>;
7-
| ^^^^^^^^^^^^^^^^^^^^^^ lifetime captured due to being mentioned in the bounds of the `impl Trait`
7+
| ^^^^^^^^^^^^^^^^^^^^^^
88

99
error: lifetime may not live long enough
1010
--> $DIR/rpitit.rs:15:5

0 commit comments

Comments
 (0)