Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use rustc_infer::infer::TyCtxtInferExt;
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,
Expand Down Expand Up @@ -332,6 +333,17 @@ fn report_mismatched_rpitit_signature<'tcx>(
hir::FnRetTy::Return(ty) => ty.span,
});

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm interested in the reason why the type gets printed that way under RTN. I would look in the HIR pretty printer to look for the culprit. Once identified, there might be a more robust solution because using span_to_snippet is more like hot patching the bug (e.g., if the source is not available (so None) I'm pretty sure we will continue to print the type that way under RTN).

Copy link
Contributor Author

@enthropy7 enthropy7 Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pretty_print_rpitit used RtnMode::ForDiagnostic by default. it gives impl Trait { T::method(..) } while RTN.

// 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 },
Expand All @@ -342,7 +354,7 @@ fn report_mismatched_rpitit_signature<'tcx>(
trait_return_span,
pre,
post,
return_ty,
return_ty: return_ty_suggestion,
unmatched_bound,
},
);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

4 changes: 2 additions & 2 deletions tests/ui/impl-trait/in-trait/foreign.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
13 changes: 13 additions & 0 deletions tests/ui/impl-trait/in-trait/refine-return-type-notation.rs
Original file line number Diff line number Diff line change
@@ -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() {}
24 changes: 24 additions & 0 deletions tests/ui/impl-trait/in-trait/refine-return-type-notation.stderr
Original file line number Diff line number Diff line change
@@ -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

Loading