Skip to content

Commit 74b9f8e

Browse files
committed
Fix unuseful span in type error in some format_args!() invocations
1 parent 7b84c9e commit 74b9f8e

File tree

3 files changed

+75
-8
lines changed

3 files changed

+75
-8
lines changed

compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub mod on_unimplemented_format;
77
mod overflow;
88
pub mod suggestions;
99

10+
use std::cmp::Reverse;
1011
use std::{fmt, iter};
1112

1213
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
@@ -136,6 +137,15 @@ pub enum DefIdOrName {
136137
Name(&'static str),
137138
}
138139

140+
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
141+
enum ErrorSortKey {
142+
SubtypeFormat(Reverse<usize>),
143+
OtherKind,
144+
ClauseTraitSized,
145+
Coerce,
146+
ClauseWellFormed,
147+
}
148+
139149
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
140150
pub fn report_fulfillment_errors(
141151
&self,
@@ -162,15 +172,42 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
162172

163173
// Ensure `T: Sized` and `T: WF` obligations come last. This lets us display diagnostics
164174
// with more relevant type information and hide redundant E0282 errors.
165-
errors.sort_by_key(|e| match e.obligation.predicate.kind().skip_binder() {
166-
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred))
167-
if self.tcx.is_lang_item(pred.def_id(), LangItem::Sized) =>
168-
{
169-
1
175+
errors.sort_by_key(|e| {
176+
let span = e.obligation.cause.span;
177+
let outer_expn_data = span.ctxt().outer_expn_data();
178+
179+
match e.obligation.predicate.kind().skip_binder() {
180+
ty::PredicateKind::Subtype(_)
181+
if matches! (
182+
outer_expn_data.kind,
183+
ExpnKind::Macro(_, name) if matches!(
184+
name.as_str().rsplit("::").next(),
185+
Some("format_args" | "format_args_nl")
186+
)
187+
) =>
188+
{
189+
let sm = self.tcx.sess.source_map();
190+
let lc = sm.span_to_location_info(span);
191+
192+
if sm.span_to_embeddable_string(span)
193+
== sm.span_to_embeddable_string(outer_expn_data.call_site)
194+
{
195+
ErrorSortKey::OtherKind
196+
} else {
197+
ErrorSortKey::SubtypeFormat(Reverse(lc.2))
198+
}
199+
}
200+
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred))
201+
if self.tcx.is_lang_item(pred.def_id(), LangItem::Sized) =>
202+
{
203+
ErrorSortKey::ClauseTraitSized
204+
}
205+
ty::PredicateKind::Coerce(_) => ErrorSortKey::Coerce,
206+
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => {
207+
ErrorSortKey::ClauseWellFormed
208+
}
209+
_ => ErrorSortKey::OtherKind,
170210
}
171-
ty::PredicateKind::Coerce(_) => 2,
172-
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => 3,
173-
_ => 0,
174211
});
175212

176213
for (index, error) in errors.iter().enumerate() {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
fn check_format_args() {
2+
print!("{:?} {a} {a:?}", [], a = 1 + 1);
3+
//~^ ERROR type annotations needed
4+
}
5+
6+
fn check_format_args_nl() {
7+
println!("{:?} {a} {a:?}", [], a = 1 + 1);
8+
//~^ ERROR type annotations needed
9+
}
10+
11+
fn main() {}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0282]: type annotations needed
2+
--> $DIR/span-format_args-issue-140578.rs:2:28
3+
|
4+
LL | print!("{:?} {a} {a:?}", [], a = 1 + 1);
5+
| ^^ cannot infer type
6+
|
7+
= note: this error originates in the macro `$crate::format_args` which comes from the expansion of the macro `print` (in Nightly builds, run with -Z macro-backtrace for more info)
8+
9+
error[E0282]: type annotations needed
10+
--> $DIR/span-format_args-issue-140578.rs:7:30
11+
|
12+
LL | println!("{:?} {a} {a:?}", [], a = 1 + 1);
13+
| ^^ cannot infer type
14+
|
15+
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
16+
17+
error: aborting due to 2 previous errors
18+
19+
For more information about this error, try `rustc --explain E0282`.

0 commit comments

Comments
 (0)