Rudimentary heuristic to insert parentheses when needed for RPIT overcaptures lint
This commit is contained in:
parent
33c245b9e9
commit
e134c74904
4 changed files with 58 additions and 6 deletions
|
@ -10,7 +10,7 @@ use rustc_hir as hir;
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::intravisit::{Visitor, walk_ty};
|
||||
use rustc_hir::{FnRetTy, GenericParamKind};
|
||||
use rustc_hir::{FnRetTy, GenericParamKind, Node};
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_middle::ty::print::{PrintTraitRefExt as _, TraitRefPrintOnlyTraitPath};
|
||||
use rustc_middle::ty::{self, Binder, ClosureKind, FnSig, PolyTraitRef, Region, Ty, TyCtxt};
|
||||
|
@ -1888,10 +1888,35 @@ pub fn impl_trait_overcapture_suggestion<'tcx>(
|
|||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
|
||||
suggs.push((
|
||||
tcx.def_span(opaque_def_id).shrink_to_hi(),
|
||||
format!(" + use<{concatenated_bounds}>"),
|
||||
));
|
||||
let opaque_hir_id = tcx.local_def_id_to_hir_id(opaque_def_id);
|
||||
// FIXME: This is a bit too conservative, since it ignores parens already written in AST.
|
||||
let (lparen, rparen) = match tcx
|
||||
.hir()
|
||||
.parent_iter(opaque_hir_id)
|
||||
.nth(1)
|
||||
.expect("expected ty to have a parent always")
|
||||
.1
|
||||
{
|
||||
Node::PathSegment(segment)
|
||||
if segment.args().paren_sugar_output().is_some_and(|ty| ty.hir_id == opaque_hir_id) =>
|
||||
{
|
||||
("(", ")")
|
||||
}
|
||||
Node::Ty(ty) => match ty.kind {
|
||||
rustc_hir::TyKind::Ptr(_) | rustc_hir::TyKind::Ref(..) => ("(", ")"),
|
||||
// FIXME: RPITs are not allowed to be nested in `impl Fn() -> ...`,
|
||||
// but we eventually could support that, and that would necessitate
|
||||
// making this more sophisticated.
|
||||
_ => ("", ""),
|
||||
},
|
||||
_ => ("", ""),
|
||||
};
|
||||
|
||||
let rpit_span = tcx.def_span(opaque_def_id);
|
||||
if !lparen.is_empty() {
|
||||
suggs.push((rpit_span.shrink_to_lo(), lparen.to_string()));
|
||||
}
|
||||
suggs.push((rpit_span.shrink_to_hi(), format!(" + use<{concatenated_bounds}>{rparen}")));
|
||||
|
||||
Some(AddPreciseCapturingForOvercapture { suggs, apit_spans })
|
||||
}
|
||||
|
|
|
@ -42,4 +42,8 @@ async fn async_fn<'a>(x: &'a ()) -> impl Sized + use<> {}
|
|||
//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
|
||||
//~| WARN this changes meaning in Rust 2024
|
||||
|
||||
pub fn parens(x: &i32) -> &(impl Clone + use<>) { x }
|
||||
//~^ ERROR `impl Clone` will capture more lifetimes than possibly intended in edition 2024
|
||||
//~| WARN this changes meaning in Rust 2024
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -42,4 +42,8 @@ async fn async_fn<'a>(x: &'a ()) -> impl Sized {}
|
|||
//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
|
||||
//~| WARN this changes meaning in Rust 2024
|
||||
|
||||
pub fn parens(x: &i32) -> &impl Clone { x }
|
||||
//~^ ERROR `impl Clone` will capture more lifetimes than possibly intended in edition 2024
|
||||
//~| WARN this changes meaning in Rust 2024
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -146,5 +146,24 @@ help: use the precise capturing `use<...>` syntax to make the captures explicit
|
|||
LL | async fn async_fn<'a>(x: &'a ()) -> impl Sized + use<> {}
|
||||
| +++++++
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
error: `impl Clone` will capture more lifetimes than possibly intended in edition 2024
|
||||
--> $DIR/overcaptures-2024.rs:45:28
|
||||
|
|
||||
LL | pub fn parens(x: &i32) -> &impl Clone { x }
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
|
||||
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
|
||||
--> $DIR/overcaptures-2024.rs:45:18
|
||||
|
|
||||
LL | pub fn parens(x: &i32) -> &impl Clone { x }
|
||||
| ^
|
||||
= note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024
|
||||
help: use the precise capturing `use<...>` syntax to make the captures explicit
|
||||
|
|
||||
LL | pub fn parens(x: &i32) -> &(impl Clone + use<>) { x }
|
||||
| + ++++++++
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue