Skip to content

Commit 849725e

Browse files
committed
fix refining_impl_trait suggestion with return_type_notation
1 parent ebf13cc commit 849725e

9 files changed

Lines changed: 60 additions & 10 deletions

File tree

compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustc_infer::infer::TyCtxtInferExt;
66
use rustc_lint_defs::builtin::{REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT_REACHABLE};
77
use rustc_middle::span_bug;
88
use rustc_middle::traits::ObligationCause;
9+
use rustc_middle::ty::print::{with_no_trimmed_paths, with_types_for_signature};
910
use rustc_middle::ty::{
1011
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable,
1112
TypeVisitableExt, TypeVisitor, TypingMode,
@@ -332,6 +333,17 @@ fn report_mismatched_rpitit_signature<'tcx>(
332333
hir::FnRetTy::Return(ty) => ty.span,
333334
});
334335

336+
// Use ForSignature mode to ensure RPITITs are printed as `impl Trait` rather than
337+
// `impl Trait { T::method(..) }` when RTN is enabled.
338+
//
339+
// We use `with_no_trimmed_paths!` to avoid triggering the `trimmed_def_paths` query,
340+
// which requires diagnostic context (via `must_produce_diag`). Since we're formatting
341+
// the type before creating the diagnostic, we need to avoid this query. This is the
342+
// standard approach used elsewhere in the compiler for formatting types in suggestions
343+
// (e.g., see `rustc_hir_typeck/src/demand.rs`).
344+
let return_ty_suggestion =
345+
with_no_trimmed_paths!(with_types_for_signature!(format!("{return_ty}")));
346+
335347
let span = unmatched_bound.unwrap_or(span);
336348
tcx.emit_node_span_lint(
337349
if is_internal { REFINING_IMPL_TRAIT_INTERNAL } else { REFINING_IMPL_TRAIT_REACHABLE },
@@ -342,7 +354,7 @@ fn report_mismatched_rpitit_signature<'tcx>(
342354
trait_return_span,
343355
pre,
344356
post,
345-
return_ty,
357+
return_ty: return_ty_suggestion,
346358
unmatched_bound,
347359
},
348360
);

compiler/rustc_hir_analysis/src/errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,7 +1023,7 @@ pub(crate) struct UnusedAssociatedTypeBounds {
10231023
#[diag(hir_analysis_rpitit_refined)]
10241024
#[note]
10251025
#[note(hir_analysis_feedback_note)]
1026-
pub(crate) struct ReturnPositionImplTraitInTraitRefined<'tcx> {
1026+
pub(crate) struct ReturnPositionImplTraitInTraitRefined {
10271027
#[suggestion(applicability = "maybe-incorrect", code = "{pre}{return_ty}{post}")]
10281028
pub impl_return_span: Span,
10291029
#[label]
@@ -1033,7 +1033,7 @@ pub(crate) struct ReturnPositionImplTraitInTraitRefined<'tcx> {
10331033

10341034
pub pre: &'static str,
10351035
pub post: &'static str,
1036-
pub return_ty: Ty<'tcx>,
1036+
pub return_ty: String,
10371037
}
10381038

10391039
#[derive(LintDiagnostic)]

tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ LL | #[warn(refining_impl_trait)]
1818
help: replace the return type so that it matches the trait
1919
|
2020
LL - fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>> {
21-
LL + fn foo(&self) -> impl Future<Output = i32> {
21+
LL + fn foo(&self) -> impl std::future::Future<Output = i32> {
2222
|
2323

2424
warning: 1 warning emitted

tests/ui/async-await/in-trait/async-example-desugared-manual.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ LL | #[warn(refining_impl_trait)]
1818
help: replace the return type so that it matches the trait
1919
|
2020
LL - fn foo(&self) -> MyFuture {
21-
LL + fn foo(&self) -> impl Future<Output = i32> {
21+
LL + fn foo(&self) -> impl std::future::Future<Output = i32> {
2222
|
2323

2424
warning: 1 warning emitted

tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ LL | fn iter(&self) -> impl 'a + Iterator<Item = I::Item<'a>> {
2929
help: replace the return type so that it matches the trait
3030
|
3131
LL - fn iter(&self) -> impl 'a + Iterator<Item = I::Item<'a>> {
32-
LL + fn iter(&self) -> impl Iterator<Item = <Self as Iterable>::Item<'_>> + '_ {
32+
LL + fn iter(&self) -> impl std::iter::Iterator<Item = <Self as Iterable>::Item<'_>> + '_ {
3333
|
3434

3535
error: aborting due to 1 previous error; 1 warning emitted

tests/ui/impl-trait/in-trait/expeced-refree-to-map-to-reearlybound-ice-108580.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ LL | fn bar(&self) -> impl Iterator + '_ {
1212
= note: `#[warn(refining_impl_trait_internal)]` (part of `#[warn(refining_impl_trait)]`) on by default
1313
help: replace the return type so that it matches the trait
1414
|
15-
LL | fn bar(&self) -> impl Iterator<Item = impl Sized> + '_ {
16-
| +++++++++++++++++++
15+
LL - fn bar(&self) -> impl Iterator + '_ {
16+
LL + fn bar(&self) -> impl std::iter::Iterator<Item = impl Sized> + '_ {
17+
|
1718

1819
warning: 1 warning emitted
1920

tests/ui/impl-trait/in-trait/foreign.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ LL | #[warn(refining_impl_trait)]
1515
help: replace the return type so that it matches the trait
1616
|
1717
LL - fn bar(self) -> Arc<String> {
18-
LL + fn bar(self) -> impl Deref<Target = impl Sized> {
18+
LL + fn bar(self) -> impl std::ops::Deref<Target = impl Sized> {
1919
|
2020

2121
warning: impl trait in impl method signature does not match trait method signature
@@ -34,7 +34,7 @@ LL | #[warn(refining_impl_trait)]
3434
help: replace the return type so that it matches the trait
3535
|
3636
LL - fn bar(self) -> Arc<String> {
37-
LL + fn bar(self) -> impl Deref<Target = impl Sized> {
37+
LL + fn bar(self) -> impl std::ops::Deref<Target = impl Sized> {
3838
|
3939

4040
warning: 2 warnings emitted
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![feature(return_type_notation)]
2+
#![deny(refining_impl_trait)]
3+
4+
trait Trait {
5+
fn f() -> impl Sized;
6+
}
7+
8+
impl Trait for () {
9+
fn f() {}
10+
//~^ ERROR impl trait in impl method signature does not match trait method signature
11+
}
12+
13+
fn main() {}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error: impl trait in impl method signature does not match trait method signature
2+
--> $DIR/refine-return-type-notation.rs:9:5
3+
|
4+
LL | fn f() -> impl Sized;
5+
| ---------- return type from trait method defined here
6+
...
7+
LL | fn f() {}
8+
| ^^^^^^
9+
|
10+
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
11+
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
12+
note: the lint level is defined here
13+
--> $DIR/refine-return-type-notation.rs:2:9
14+
|
15+
LL | #![deny(refining_impl_trait)]
16+
| ^^^^^^^^^^^^^^^^^^^
17+
= note: `#[deny(refining_impl_trait_internal)]` implied by `#[deny(refining_impl_trait)]`
18+
help: replace the return type so that it matches the trait
19+
|
20+
LL | fn f()-> impl Sized {}
21+
| +++++++++++++
22+
23+
error: aborting due to 1 previous error
24+

0 commit comments

Comments
 (0)