Skip to content

Commit f103076

Browse files
authored
Rollup merge of #134142 - compiler-errors:paren-sug, r=jieyouxu
Rudimentary heuristic to insert parentheses when needed for RPIT overcaptures lint We don't have basically any preexisting machinery to detect when parentheses are needed for *types*. AFAICT, all of the diagnostics we have for opaques just... fail when they suggest `+ 'a` when that's ambiguous. Fixes #132853
2 parents 16b6493 + e134c74 commit f103076

File tree

4 files changed

+58
-6
lines changed

4 files changed

+58
-6
lines changed

compiler/rustc_trait_selection/src/errors.rs

+30-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_hir as hir;
1010
use rustc_hir::def::DefKind;
1111
use rustc_hir::def_id::{DefId, LocalDefId};
1212
use rustc_hir::intravisit::{Visitor, walk_ty};
13-
use rustc_hir::{FnRetTy, GenericParamKind};
13+
use rustc_hir::{FnRetTy, GenericParamKind, Node};
1414
use rustc_macros::{Diagnostic, Subdiagnostic};
1515
use rustc_middle::ty::print::{PrintTraitRefExt as _, TraitRefPrintOnlyTraitPath};
1616
use rustc_middle::ty::{self, Binder, ClosureKind, FnSig, PolyTraitRef, Region, Ty, TyCtxt};
@@ -1888,10 +1888,35 @@ pub fn impl_trait_overcapture_suggestion<'tcx>(
18881888
.collect::<Vec<_>>()
18891889
.join(", ");
18901890

1891-
suggs.push((
1892-
tcx.def_span(opaque_def_id).shrink_to_hi(),
1893-
format!(" + use<{concatenated_bounds}>"),
1894-
));
1891+
let opaque_hir_id = tcx.local_def_id_to_hir_id(opaque_def_id);
1892+
// FIXME: This is a bit too conservative, since it ignores parens already written in AST.
1893+
let (lparen, rparen) = match tcx
1894+
.hir()
1895+
.parent_iter(opaque_hir_id)
1896+
.nth(1)
1897+
.expect("expected ty to have a parent always")
1898+
.1
1899+
{
1900+
Node::PathSegment(segment)
1901+
if segment.args().paren_sugar_output().is_some_and(|ty| ty.hir_id == opaque_hir_id) =>
1902+
{
1903+
("(", ")")
1904+
}
1905+
Node::Ty(ty) => match ty.kind {
1906+
rustc_hir::TyKind::Ptr(_) | rustc_hir::TyKind::Ref(..) => ("(", ")"),
1907+
// FIXME: RPITs are not allowed to be nested in `impl Fn() -> ...`,
1908+
// but we eventually could support that, and that would necessitate
1909+
// making this more sophisticated.
1910+
_ => ("", ""),
1911+
},
1912+
_ => ("", ""),
1913+
};
1914+
1915+
let rpit_span = tcx.def_span(opaque_def_id);
1916+
if !lparen.is_empty() {
1917+
suggs.push((rpit_span.shrink_to_lo(), lparen.to_string()));
1918+
}
1919+
suggs.push((rpit_span.shrink_to_hi(), format!(" + use<{concatenated_bounds}>{rparen}")));
18951920

18961921
Some(AddPreciseCapturingForOvercapture { suggs, apit_spans })
18971922
}

tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed

+4
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,8 @@ async fn async_fn<'a>(x: &'a ()) -> impl Sized + use<> {}
4242
//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
4343
//~| WARN this changes meaning in Rust 2024
4444

45+
pub fn parens(x: &i32) -> &(impl Clone + use<>) { x }
46+
//~^ ERROR `impl Clone` will capture more lifetimes than possibly intended in edition 2024
47+
//~| WARN this changes meaning in Rust 2024
48+
4549
fn main() {}

tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs

+4
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,8 @@ async fn async_fn<'a>(x: &'a ()) -> impl Sized {}
4242
//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
4343
//~| WARN this changes meaning in Rust 2024
4444

45+
pub fn parens(x: &i32) -> &impl Clone { x }
46+
//~^ ERROR `impl Clone` will capture more lifetimes than possibly intended in edition 2024
47+
//~| WARN this changes meaning in Rust 2024
48+
4549
fn main() {}

tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr

+20-1
Original file line numberDiff line numberDiff line change
@@ -146,5 +146,24 @@ help: use the precise capturing `use<...>` syntax to make the captures explicit
146146
LL | async fn async_fn<'a>(x: &'a ()) -> impl Sized + use<> {}
147147
| +++++++
148148

149-
error: aborting due to 7 previous errors
149+
error: `impl Clone` will capture more lifetimes than possibly intended in edition 2024
150+
--> $DIR/overcaptures-2024.rs:45:28
151+
|
152+
LL | pub fn parens(x: &i32) -> &impl Clone { x }
153+
| ^^^^^^^^^^
154+
|
155+
= warning: this changes meaning in Rust 2024
156+
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
157+
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
158+
--> $DIR/overcaptures-2024.rs:45:18
159+
|
160+
LL | pub fn parens(x: &i32) -> &impl Clone { x }
161+
| ^
162+
= note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024
163+
help: use the precise capturing `use<...>` syntax to make the captures explicit
164+
|
165+
LL | pub fn parens(x: &i32) -> &(impl Clone + use<>) { x }
166+
| + ++++++++
167+
168+
error: aborting due to 8 previous errors
150169

0 commit comments

Comments
 (0)