Skip to content

Commit 0aa6b1e

Browse files
Make spans a bit better
1 parent 1e4fd21 commit 0aa6b1e

File tree

7 files changed

+43
-25
lines changed

7 files changed

+43
-25
lines changed

compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::diagnostics::utils::{
99
FieldInnerTy, FieldMap, HasFieldMap, SetOnce, SpannedOption, SubdiagnosticKind,
1010
};
1111
use proc_macro2::{Ident, Span, TokenStream};
12-
use quote::{format_ident, quote};
12+
use quote::{format_ident, quote, quote_spanned};
1313
use syn::Token;
1414
use syn::{parse_quote, spanned::Spanned, Attribute, Meta, Path, Type};
1515
use synstructure::{BindingInfo, Structure, VariantInfo};
@@ -251,7 +251,8 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
251251
let diag = &self.parent.diag;
252252

253253
let field = binding_info.ast();
254-
let field_binding = &binding_info.binding;
254+
let mut field_binding = binding_info.binding.clone();
255+
field_binding.set_span(field.ty.span());
255256

256257
let ident = field.ident.as_ref().unwrap();
257258
let ident = format_ident!("{}", ident); // strip `r#` prefix, if present
@@ -284,9 +285,9 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
284285
name == "primary_span" && matches!(inner_ty, FieldInnerTy::Vec(_));
285286
let (binding, needs_destructure) = if needs_clone {
286287
// `primary_span` can accept a `Vec<Span>` so don't destructure that.
287-
(quote! { #field_binding.clone() }, false)
288+
(quote_spanned! {inner_ty.span()=> #field_binding.clone() }, false)
288289
} else {
289-
(quote! { #field_binding }, true)
290+
(quote_spanned! {inner_ty.span()=> #field_binding }, true)
290291
};
291292

292293
let generated_code = self

compiler/rustc_macros/src/diagnostics/subdiagnostic.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -209,18 +209,20 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
209209
}
210210

211211
/// Generates the code for a field with no attributes.
212-
fn generate_field_set_arg(&mut self, binding: &BindingInfo<'_>) -> TokenStream {
213-
let ast = binding.ast();
214-
212+
fn generate_field_set_arg(&mut self, binding_info: &BindingInfo<'_>) -> TokenStream {
215213
let diag = &self.parent.diag;
216-
let ident = ast.ident.as_ref().unwrap();
217-
// strip `r#` prefix, if present
218-
let ident = format_ident!("{}", ident);
214+
215+
let field = binding_info.ast();
216+
let mut field_binding = binding_info.binding.clone();
217+
field_binding.set_span(field.ty.span());
218+
219+
let ident = field.ident.as_ref().unwrap();
220+
let ident = format_ident!("{}", ident); // strip `r#` prefix, if present
219221

220222
quote! {
221223
#diag.set_arg(
222224
stringify!(#ident),
223-
#binding
225+
#field_binding
224226
);
225227
}
226228
}
@@ -397,7 +399,8 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
397399
clone_suggestion_code: bool,
398400
) -> Result<TokenStream, DiagnosticDeriveError> {
399401
let span = attr.span().unwrap();
400-
let ident = &list.path.segments.last().unwrap().ident;
402+
let mut ident = list.path.segments.last().unwrap().ident.clone();
403+
ident.set_span(info.ty.span());
401404
let name = ident.to_string();
402405
let name = name.as_str();
403406

@@ -496,7 +499,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
496499
.variant
497500
.bindings()
498501
.iter()
499-
.filter(|binding| !binding.ast().attrs.is_empty())
502+
.filter(|binding| !should_generate_set_arg(binding.ast()))
500503
.map(|binding| self.generate_field_attr_code(binding, kind_stats))
501504
.collect();
502505

compiler/rustc_macros/src/diagnostics/utils.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,12 @@ impl<'ty> FieldInnerTy<'ty> {
207207
FieldInnerTy::Plain(..) => quote! { #inner },
208208
}
209209
}
210+
211+
pub fn span(&self) -> proc_macro2::Span {
212+
match self {
213+
FieldInnerTy::Option(ty) | FieldInnerTy::Vec(ty) | FieldInnerTy::Plain(ty) => ty.span(),
214+
}
215+
}
210216
}
211217

212218
/// Field information passed to the builder. Deliberately omits attrs to discourage the

tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,21 @@ fluent_messages! { "./example.ftl" }
2727
struct NotIntoDiagnosticArg;
2828

2929
#[derive(Diagnostic)]
30-
//~^ ERROR the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied
3130
#[diag(no_crate_example)]
3231
struct Test {
3332
#[primary_span]
3433
span: Span,
3534
/// A doc comment
3635
arg: NotIntoDiagnosticArg,
36+
//~^ ERROR the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied
3737
}
3838

3939
#[derive(Subdiagnostic)]
40-
//~^ ERROR the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied
4140
#[label(no_crate_example)]
4241
struct SubTest {
4342
#[primary_span]
4443
span: Span,
4544
/// A doc comment
4645
arg: NotIntoDiagnosticArg,
46+
//~^ ERROR the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied
4747
}

tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
error[E0277]: the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied
2-
--> $DIR/diagnostic-derive-doc-comment-field.rs:29:10
2+
--> $DIR/diagnostic-derive-doc-comment-field.rs:35:10
33
|
44
LL | #[derive(Diagnostic)]
5-
| ^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `NotIntoDiagnosticArg`
5+
| ---------- required by a bound introduced by this call
6+
...
7+
LL | arg: NotIntoDiagnosticArg,
8+
| ^^^^^^^^^^^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `NotIntoDiagnosticArg`
69
|
710
= help: the following other types implement trait `IntoDiagnosticArg`:
811
&'a T
@@ -16,13 +19,16 @@ LL | #[derive(Diagnostic)]
1619
and 42 others
1720
note: required by a bound in `DiagnosticBuilder::<'a, G>::set_arg`
1821
--> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:747:5
19-
= note: this error originates in the derive macro `Diagnostic` which comes from the expansion of the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info)
22+
= note: this error originates in the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info)
2023

2124
error[E0277]: the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied
22-
--> $DIR/diagnostic-derive-doc-comment-field.rs:39:10
25+
--> $DIR/diagnostic-derive-doc-comment-field.rs:45:10
2326
|
2427
LL | #[derive(Subdiagnostic)]
25-
| ^^^^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `NotIntoDiagnosticArg`
28+
| ------------- required by a bound introduced by this call
29+
...
30+
LL | arg: NotIntoDiagnosticArg,
31+
| ^^^^^^^^^^^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `NotIntoDiagnosticArg`
2632
|
2733
= help: the following other types implement trait `IntoDiagnosticArg`:
2834
&'a T
@@ -36,7 +42,6 @@ LL | #[derive(Subdiagnostic)]
3642
and 42 others
3743
note: required by a bound in `Diagnostic::set_arg`
3844
--> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:964:5
39-
= note: this error originates in the derive macro `Subdiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
4045

4146
error: aborting due to 2 previous errors
4247

tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,12 +339,12 @@ struct ErrorWithDefaultLabelAttr<'a> {
339339
}
340340

341341
#[derive(Diagnostic)]
342-
//~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied
343342
#[diag(no_crate_example, code = "E0123")]
344343
struct ArgFieldWithoutSkip {
345344
#[primary_span]
346345
span: Span,
347346
other: Hello,
347+
//~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied
348348
}
349349

350350
#[derive(Diagnostic)]

tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -641,15 +641,18 @@ LL | #[derive(Diagnostic)]
641641
= note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
642642

643643
error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied
644-
--> $DIR/diagnostic-derive.rs:341:10
644+
--> $DIR/diagnostic-derive.rs:346:12
645645
|
646646
LL | #[derive(Diagnostic)]
647-
| ^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello`
647+
| ---------- required by a bound introduced by this call
648+
...
649+
LL | other: Hello,
650+
| ^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello`
648651
|
649652
= help: normalized in stderr
650653
note: required by a bound in `DiagnosticBuilder::<'a, G>::set_arg`
651654
--> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:LL:CC
652-
= note: this error originates in the derive macro `Diagnostic` which comes from the expansion of the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info)
655+
= note: this error originates in the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info)
653656

654657
error: aborting due to 84 previous errors
655658

0 commit comments

Comments
 (0)