Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Clarify implicit captures for RPITIT
  • Loading branch information
compiler-errors authored and workingjubilee committed Oct 10, 2024
commit 36076ecdc726c4e1104e70df2d142f39501a4f48
3 changes: 3 additions & 0 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
25 changes: 16 additions & 9 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_hir_analysis/src/errors/precise_captures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/impl-trait/precise-capturing/rpitit.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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<Self>;
| ^^^^^^^^^^^^^^^^^^^^^^ 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
Expand Down