Adding #[diagnostic::do_not_recommend] to a blanket impl causes trait error spans to regress from the method call to the outer expression in method chains.
The trait resolution result itself does not change. Only the diagnostic span changes.
I tried this code:
trait A {}
trait B {}
#[diagnostic::do_not_recommend]
impl<T: B> A for T {}
struct X;
trait Start {
fn start(self) -> Self;
}
trait Ext {
fn foo(self) -> Self
where
Self: Sized + A;
}
trait Finish {
fn finish(self);
}
impl<T> Start for T {
fn start(self) -> Self {
self
}
}
impl<T> Ext for T {
fn foo(self) -> Self
where
Self: Sized + A,
{
self
}
}
impl<T> Finish for T {
fn finish(self) {}
}
fn main() {
X.start().foo().finish();
}
I expected to see this happen:
The primary error span should remain attached to the method call that introduces the A obligation, even when the blanket impl is annotated with #[diagnostic::do_not_recommend].
Without the attribute, the compiler produces a precise span on .foo(), which appears to be the expected diagnostic behavior.
error[E0277]: the trait bound `X: A` is not satisfied
--> do_not_recommend_test.rs:43:15
|
43 | X.start().foo().finish();
| ^^^ unsatisfied trait bound
Instead, this happened:
Adding #[diagnostic::do_not_recommend] causes the primary span to regress from the method call to the receiver expression (X.start()).
The trait error itself is still correct, but the diagnostic loses precision and points to a larger portion of the method chain, making the actual source of the failed obligation less clear.
error[E0277]: the trait bound `X: A` is not satisfied
--> do_not_recommend_test.rs:43:5
|
43 | X.start().foo().finish();
| ^^^^^^^^^ unsatisfied trait bound
Meta
rustc --version --verbose:
rustc 1.95.0 (59807616e 2026-04-14)
binary: rustc
commit-hash: 59807616e1fa2540724bfbac14d7976d7e4a3860
commit-date: 2026-04-14
host: x86_64-unknown-linux-gnu
release: 1.95.0
LLVM version: 22.1.2
rustc +nightly --version --verbose:
rustc 1.97.0-nightly (f964de49b 2026-05-07)
binary: rustc
commit-hash: f964de49bcb561e5c6c725bb37201e11d852daf0
commit-date: 2026-05-07
host: x86_64-unknown-linux-gnu
release: 1.97.0-nightly
LLVM version: 22.1.4
Backtrace
Adding
#[diagnostic::do_not_recommend]to a blanket impl causes trait error spans to regress from the method call to the outer expression in method chains.The trait resolution result itself does not change. Only the diagnostic span changes.
I tried this code:
I expected to see this happen:
The primary error span should remain attached to the method call that introduces the
Aobligation, even when the blanket impl is annotated with#[diagnostic::do_not_recommend].Without the attribute, the compiler produces a precise span on
.foo(), which appears to be the expected diagnostic behavior.Instead, this happened:
Adding
#[diagnostic::do_not_recommend]causes the primary span to regress from the method call to the receiver expression (X.start()).The trait error itself is still correct, but the diagnostic loses precision and points to a larger portion of the method chain, making the actual source of the failed obligation less clear.
Meta
rustc --version --verbose:rustc +nightly --version --verbose:Backtrace