fix refining_impl_trait suggestion with return_type_notation

This commit is contained in:
enthropy7
2026-01-27 17:13:42 +03:00
parent 035b01b794
commit bcde3fc780
9 changed files with 60 additions and 10 deletions
@@ -6,6 +6,7 @@
use rustc_lint_defs::builtin::{REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT_REACHABLE};
use rustc_middle::span_bug;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::print::{with_no_trimmed_paths, with_types_for_signature};
use rustc_middle::ty::{
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt, TypeVisitor, TypingMode,
@@ -332,6 +333,17 @@ fn report_mismatched_rpitit_signature<'tcx>(
hir::FnRetTy::Return(ty) => ty.span,
});
// Use ForSignature mode to ensure RPITITs are printed as `impl Trait` rather than
// `impl Trait { T::method(..) }` when RTN is enabled.
//
// We use `with_no_trimmed_paths!` to avoid triggering the `trimmed_def_paths` query,
// which requires diagnostic context (via `must_produce_diag`). Since we're formatting
// the type before creating the diagnostic, we need to avoid this query. This is the
// standard approach used elsewhere in the compiler for formatting types in suggestions
// (e.g., see `rustc_hir_typeck/src/demand.rs`).
let return_ty_suggestion =
with_no_trimmed_paths!(with_types_for_signature!(format!("{return_ty}")));
let span = unmatched_bound.unwrap_or(span);
tcx.emit_node_span_lint(
if is_internal { REFINING_IMPL_TRAIT_INTERNAL } else { REFINING_IMPL_TRAIT_REACHABLE },
@@ -342,7 +354,7 @@ fn report_mismatched_rpitit_signature<'tcx>(
trait_return_span,
pre,
post,
return_ty,
return_ty: return_ty_suggestion,
unmatched_bound,
},
);
+2 -2
View File
@@ -1122,7 +1122,7 @@ pub(crate) struct UnusedAssociatedTypeBounds {
#[note(
"we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information"
)]
pub(crate) struct ReturnPositionImplTraitInTraitRefined<'tcx> {
pub(crate) struct ReturnPositionImplTraitInTraitRefined {
#[suggestion(
"replace the return type so that it matches the trait",
applicability = "maybe-incorrect",
@@ -1136,7 +1136,7 @@ pub(crate) struct ReturnPositionImplTraitInTraitRefined<'tcx> {
pub pre: &'static str,
pub post: &'static str,
pub return_ty: Ty<'tcx>,
pub return_ty: String,
}
#[derive(LintDiagnostic)]
@@ -18,7 +18,7 @@ LL | #[warn(refining_impl_trait)]
help: replace the return type so that it matches the trait
|
LL - fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>> {
LL + fn foo(&self) -> impl Future<Output = i32> {
LL + fn foo(&self) -> impl std::future::Future<Output = i32> {
|
warning: 1 warning emitted
@@ -18,7 +18,7 @@ LL | #[warn(refining_impl_trait)]
help: replace the return type so that it matches the trait
|
LL - fn foo(&self) -> MyFuture {
LL + fn foo(&self) -> impl Future<Output = i32> {
LL + fn foo(&self) -> impl std::future::Future<Output = i32> {
|
warning: 1 warning emitted
@@ -29,7 +29,7 @@ LL | fn iter(&self) -> impl 'a + Iterator<Item = I::Item<'a>> {
help: replace the return type so that it matches the trait
|
LL - fn iter(&self) -> impl 'a + Iterator<Item = I::Item<'a>> {
LL + fn iter(&self) -> impl Iterator<Item = <Self as Iterable>::Item<'_>> + '_ {
LL + fn iter(&self) -> impl std::iter::Iterator<Item = <Self as Iterable>::Item<'_>> + '_ {
|
error: aborting due to 1 previous error; 1 warning emitted
@@ -12,8 +12,9 @@ LL | fn bar(&self) -> impl Iterator + '_ {
= note: `#[warn(refining_impl_trait_internal)]` (part of `#[warn(refining_impl_trait)]`) on by default
help: replace the return type so that it matches the trait
|
LL | fn bar(&self) -> impl Iterator<Item = impl Sized> + '_ {
| +++++++++++++++++++
LL - fn bar(&self) -> impl Iterator + '_ {
LL + fn bar(&self) -> impl std::iter::Iterator<Item = impl Sized> + '_ {
|
warning: 1 warning emitted
+2 -2
View File
@@ -15,7 +15,7 @@ LL | #[warn(refining_impl_trait)]
help: replace the return type so that it matches the trait
|
LL - fn bar(self) -> Arc<String> {
LL + fn bar(self) -> impl Deref<Target = impl Sized> {
LL + fn bar(self) -> impl std::ops::Deref<Target = impl Sized> {
|
warning: impl trait in impl method signature does not match trait method signature
@@ -34,7 +34,7 @@ LL | #[warn(refining_impl_trait)]
help: replace the return type so that it matches the trait
|
LL - fn bar(self) -> Arc<String> {
LL + fn bar(self) -> impl Deref<Target = impl Sized> {
LL + fn bar(self) -> impl std::ops::Deref<Target = impl Sized> {
|
warning: 2 warnings emitted
@@ -0,0 +1,13 @@
#![feature(return_type_notation)]
#![deny(refining_impl_trait)]
trait Trait {
fn f() -> impl Sized;
}
impl Trait for () {
fn f() {}
//~^ ERROR impl trait in impl method signature does not match trait method signature
}
fn main() {}
@@ -0,0 +1,24 @@
error: impl trait in impl method signature does not match trait method signature
--> $DIR/refine-return-type-notation.rs:9:5
|
LL | fn f() -> impl Sized;
| ---------- return type from trait method defined here
...
LL | fn f() {}
| ^^^^^^
|
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
note: the lint level is defined here
--> $DIR/refine-return-type-notation.rs:2:9
|
LL | #![deny(refining_impl_trait)]
| ^^^^^^^^^^^^^^^^^^^
= note: `#[deny(refining_impl_trait_internal)]` implied by `#[deny(refining_impl_trait)]`
help: replace the return type so that it matches the trait
|
LL | fn f()-> impl Sized {}
| +++++++++++++
error: aborting due to 1 previous error