Skip to content

Commit c45e831

Browse files
committed
Auto merge of #124228 - compiler-errors:lint-overcaptures, r=oli-obk
Warn against changes in opaque lifetime captures in 2024 Adds a (mostly[^1]) machine-applicable lint `IMPL_TRAIT_OVERCAPTURES` which detects cases where we will capture more lifetimes in edition 2024 than in edition <= 2021, which may lead to erroneous borrowck errors. This lint is gated behind the `precise_capturing` feature gate and marked `Allow` for now. [^1]: Except when there are APITs -- I may work on that soon r? oli-obk
2 parents 58426f4 + 052de1d commit c45e831

14 files changed

Lines changed: 694 additions & 38 deletions

File tree

‎compiler/rustc_ast_lowering/src/lib.rs‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,7 +1407,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
14071407
bounds,
14081408
fn_kind,
14091409
itctx,
1410-
precise_capturing.as_deref().map(|(args,_)| args.as_slice()),
1410+
precise_capturing.as_deref().map(|(args,span)| (args.as_slice(),*span)),
14111411
),
14121412
ImplTraitContext::Universal => {
14131413
ifletSome(&(_, span)) = precise_capturing.as_deref(){
@@ -1523,7 +1523,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15231523
bounds:&GenericBounds,
15241524
fn_kind:Option<FnDeclKind>,
15251525
itctx:ImplTraitContext,
1526-
precise_capturing_args:Option<&[PreciseCapturingArg]>,
1526+
precise_capturing_args:Option<(&[PreciseCapturingArg],Span)>,
15271527
) -> hir::TyKind<'hir>{
15281528
// Make sure we know that some funky desugaring has been going on here.
15291529
// This is a first: there is code in other places like for loop
@@ -1533,7 +1533,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15331533
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span,None);
15341534

15351535
let captured_lifetimes_to_duplicate =
1536-
ifletSome(precise_capturing) = precise_capturing_args {
1536+
ifletSome((precise_capturing, _)) = precise_capturing_args {
15371537
// We'll actually validate these later on; all we need is the list of
15381538
// lifetimes to duplicate during this portion of lowering.
15391539
precise_capturing
@@ -1607,7 +1607,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16071607
captured_lifetimes_to_duplicate:FxIndexSet<Lifetime>,
16081608
span:Span,
16091609
opaque_ty_span:Span,
1610-
precise_capturing_args:Option<&[PreciseCapturingArg]>,
1610+
precise_capturing_args:Option<(&[PreciseCapturingArg],Span)>,
16111611
lower_item_bounds:implFnOnce(&mutSelf) -> &'hir[hir::GenericBound<'hir>],
16121612
) -> hir::TyKind<'hir>{
16131613
let opaque_ty_def_id = self.create_def(
@@ -1698,8 +1698,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16981698
this.with_remapping(captured_to_synthesized_mapping, |this| {
16991699
(
17001700
lower_item_bounds(this),
1701-
precise_capturing_args.map(|precise_capturing| {
1702-
this.lower_precise_capturing_args(precise_capturing)
1701+
precise_capturing_args.map(|(precise_capturing, span)| {
1702+
(
1703+
this.lower_precise_capturing_args(precise_capturing),
1704+
this.lower_span(span),
1705+
)
17031706
}),
17041707
)
17051708
});

‎compiler/rustc_hir/src/hir.rs‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2631,7 +2631,7 @@ pub struct OpaqueTy<'hir> {
26312631
/// lowered as an associated type.
26322632
pubin_trait:bool,
26332633
/// List of arguments captured via `impl use<'a, P, ...> Trait` syntax.
2634-
pubprecise_capturing_args:Option<&'hir[PreciseCapturingArg<'hir>]>,
2634+
pubprecise_capturing_args:Option<(&'hir[PreciseCapturingArg<'hir>],Span)>,
26352635
}
26362636

26372637
#[derive(Debug,Clone,Copy,HashStable_Generic)]
@@ -2641,6 +2641,15 @@ pub enum PreciseCapturingArg<'hir> {
26412641
Param(PreciseCapturingNonLifetimeArg),
26422642
}
26432643

2644+
implPreciseCapturingArg<'_>{
2645+
pubfnhir_id(self) -> HirId{
2646+
matchself{
2647+
PreciseCapturingArg::Lifetime(lt) => lt.hir_id,
2648+
PreciseCapturingArg::Param(param) => param.hir_id,
2649+
}
2650+
}
2651+
}
2652+
26442653
/// We need to have a [`Node`] for the [`HirId`] that we attach the type/const param
26452654
/// resolution to. Lifetimes don't have this problem, and for them, it's actually
26462655
/// kind of detrimental to use a custom node type versus just using [`Lifetime`],

‎compiler/rustc_hir/src/intravisit.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
533533
try_visit!(visitor.visit_id(item.hir_id()));
534534
try_visit!(walk_generics(visitor, generics));
535535
walk_list!(visitor, visit_param_bound, bounds);
536-
ifletSome(precise_capturing_args) = precise_capturing_args {
536+
ifletSome((precise_capturing_args, _)) = precise_capturing_args {
537537
for arg in precise_capturing_args {
538538
try_visit!(visitor.visit_precise_capturing_arg(arg));
539539
}

‎compiler/rustc_hir_analysis/src/check/check.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ fn sanity_check_found_hidden_type<'tcx>(
486486
fncheck_opaque_precise_captures<'tcx>(tcx:TyCtxt<'tcx>,opaque_def_id:LocalDefId){
487487
let hir::OpaqueTy{ precise_capturing_args, .. } =
488488
*tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
489-
letSome(precise_capturing_args) = precise_capturing_args else{
489+
letSome((precise_capturing_args, _)) = precise_capturing_args else{
490490
// No precise capturing args; nothing to validate
491491
return;
492492
};

‎compiler/rustc_lint/messages.ftl‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,17 @@ lint_identifier_uncommon_codepoints = identifier contains {$codepoints_len ->
269269
270270
lint_ignored_unless_crate_specified = {$level}({$name}) is ignored unless specified at crate level
271271
272+
lint_impl_trait_overcaptures = `{$self_ty}` will capture more lifetimes than possibly intended in edition 2024
273+
.note = specifically, {$num_captured->
274+
[one] this lifetime is
275+
*[other] these lifetimes are
276+
} in scope but not mentioned in the type's bounds
277+
.note2 = all lifetimes in scope will be captured by `impl Trait`s in edition 2024
278+
.suggestion = use the precise capturing `use<...>` syntax to make the captures explicit
279+
280+
lint_impl_trait_redundant_captures = all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
281+
.suggestion = remove the `use<...>` syntax
282+
272283
lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
273284
.label = not FFI-safe
274285
.note = the type is defined here

0 commit comments

Comments
 (0)