Skip to content

Commit df2adc4

Browse files
committed
Print all labels, even if they have no span. Fall back to main item's span.
1 parent 21ce587 commit df2adc4

File tree

11 files changed

+110
-51
lines changed

11 files changed

+110
-51
lines changed

compiler/rustc_error_messages/locales/en-US/passes.ftl

+4-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ passes_no_coverage_not_coverable =
4747
4848
passes_should_be_applied_to_fn =
4949
attribute should be applied to a function definition
50-
.label = not a function definition
50+
.label = {$on_crate ->
51+
[true] cannot be applied to crates
52+
*[false] not a function definition
53+
}
5154
5255
passes_naked_tracked_caller =
5356
cannot use `#[track_caller]` with `#[naked]`

compiler/rustc_errors/src/emitter.rs

+35-12
Original file line numberDiff line numberDiff line change
@@ -2210,22 +2210,45 @@ impl FileWithAnnotatedLines {
22102210

22112211
if let Some(ref sm) = emitter.source_map() {
22122212
for span_label in msp.span_labels() {
2213+
let fixup_lo_hi = |span: Span| {
2214+
let lo = sm.lookup_char_pos(span.lo());
2215+
let mut hi = sm.lookup_char_pos(span.hi());
2216+
2217+
// Watch out for "empty spans". If we get a span like 6..6, we
2218+
// want to just display a `^` at 6, so convert that to
2219+
// 6..7. This is degenerate input, but it's best to degrade
2220+
// gracefully -- and the parser likes to supply a span like
2221+
// that for EOF, in particular.
2222+
2223+
if lo.col_display == hi.col_display && lo.line == hi.line {
2224+
hi.col_display += 1;
2225+
}
2226+
(lo, hi)
2227+
};
2228+
22132229
if span_label.span.is_dummy() {
2230+
if let Some(span) = msp.primary_span() {
2231+
// if we don't know where to render the annotation, emit it as a note
2232+
// on the primary span.
2233+
2234+
let (lo, hi) = fixup_lo_hi(span);
2235+
2236+
let ann = Annotation {
2237+
start_col: lo.col_display,
2238+
end_col: hi.col_display,
2239+
is_primary: span_label.is_primary,
2240+
label: span_label
2241+
.label
2242+
.as_ref()
2243+
.map(|m| emitter.translate_message(m, args).to_string()),
2244+
annotation_type: AnnotationType::Singleline,
2245+
};
2246+
add_annotation_to_file(&mut output, lo.file, lo.line, ann);
2247+
}
22142248
continue;
22152249
}
22162250

2217-
let lo = sm.lookup_char_pos(span_label.span.lo());
2218-
let mut hi = sm.lookup_char_pos(span_label.span.hi());
2219-
2220-
// Watch out for "empty spans". If we get a span like 6..6, we
2221-
// want to just display a `^` at 6, so convert that to
2222-
// 6..7. This is degenerate input, but it's best to degrade
2223-
// gracefully -- and the parser likes to supply a span like
2224-
// that for EOF, in particular.
2225-
2226-
if lo.col_display == hi.col_display && lo.line == hi.line {
2227-
hi.col_display += 1;
2228-
}
2251+
let (lo, hi) = fixup_lo_hi(span_label.span);
22292252

22302253
if lo.line != hi.line {
22312254
let ml = MultilineAnnotation {

compiler/rustc_passes/src/check_attr.rs

+42-13
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,13 @@ impl CheckAttrVisitor<'_> {
119119
}
120120
sym::naked => self.check_naked(hir_id, attr, span, target),
121121
sym::rustc_legacy_const_generics => {
122-
self.check_rustc_legacy_const_generics(&attr, span, target, item)
122+
self.check_rustc_legacy_const_generics(hir_id, &attr, span, target, item)
123123
}
124124
sym::rustc_lint_query_instability => {
125-
self.check_rustc_lint_query_instability(&attr, span, target)
125+
self.check_rustc_lint_query_instability(hir_id, &attr, span, target)
126126
}
127127
sym::rustc_lint_diagnostics => {
128-
self.check_rustc_lint_diagnostics(&attr, span, target)
128+
self.check_rustc_lint_diagnostics(hir_id, &attr, span, target)
129129
}
130130
sym::rustc_lint_opt_ty => self.check_rustc_lint_opt_ty(&attr, span, target),
131131
sym::rustc_lint_opt_deny_field_access => {
@@ -135,7 +135,9 @@ impl CheckAttrVisitor<'_> {
135135
| sym::rustc_dirty
136136
| sym::rustc_if_this_changed
137137
| sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(&attr),
138-
sym::cmse_nonsecure_entry => self.check_cmse_nonsecure_entry(attr, span, target),
138+
sym::cmse_nonsecure_entry => {
139+
self.check_cmse_nonsecure_entry(hir_id, attr, span, target)
140+
}
139141
sym::collapse_debuginfo => self.check_collapse_debuginfo(attr, span, target),
140142
sym::const_trait => self.check_const_trait(attr, span, target),
141143
sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target),
@@ -386,21 +388,29 @@ impl CheckAttrVisitor<'_> {
386388
self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
387389
attr_span: attr.span,
388390
defn_span: span,
391+
on_crate: hir_id == CRATE_HIR_ID,
389392
});
390393
false
391394
}
392395
}
393396
}
394397

395398
/// Checks if `#[cmse_nonsecure_entry]` is applied to a function definition.
396-
fn check_cmse_nonsecure_entry(&self, attr: &Attribute, span: Span, target: Target) -> bool {
399+
fn check_cmse_nonsecure_entry(
400+
&self,
401+
hir_id: HirId,
402+
attr: &Attribute,
403+
span: Span,
404+
target: Target,
405+
) -> bool {
397406
match target {
398407
Target::Fn
399408
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
400409
_ => {
401410
self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
402411
attr_span: attr.span,
403412
defn_span: span,
413+
on_crate: hir_id == CRATE_HIR_ID,
404414
});
405415
false
406416
}
@@ -465,9 +475,11 @@ impl CheckAttrVisitor<'_> {
465475
true
466476
}
467477
_ => {
468-
self.tcx
469-
.sess
470-
.emit_err(errors::TrackedCallerWrongLocation { attr_span, defn_span: span });
478+
self.tcx.sess.emit_err(errors::TrackedCallerWrongLocation {
479+
attr_span,
480+
defn_span: span,
481+
on_crate: hir_id == CRATE_HIR_ID,
482+
});
471483
false
472484
}
473485
}
@@ -576,6 +588,7 @@ impl CheckAttrVisitor<'_> {
576588
self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
577589
attr_span: attr.span,
578590
defn_span: span,
591+
on_crate: hir_id == CRATE_HIR_ID,
579592
});
580593
false
581594
}
@@ -1240,7 +1253,7 @@ impl CheckAttrVisitor<'_> {
12401253
UNUSED_ATTRIBUTES,
12411254
hir_id,
12421255
attr.span,
1243-
errors::Cold { span },
1256+
errors::Cold { span, on_crate: hir_id == CRATE_HIR_ID },
12441257
);
12451258
}
12461259
}
@@ -1376,6 +1389,7 @@ impl CheckAttrVisitor<'_> {
13761389
/// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument.
13771390
fn check_rustc_legacy_const_generics(
13781391
&self,
1392+
hir_id: HirId,
13791393
attr: &Attribute,
13801394
span: Span,
13811395
target: Target,
@@ -1386,6 +1400,7 @@ impl CheckAttrVisitor<'_> {
13861400
self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
13871401
attr_span: attr.span,
13881402
defn_span: span,
1403+
on_crate: hir_id == CRATE_HIR_ID,
13891404
});
13901405
return false;
13911406
}
@@ -1450,12 +1465,19 @@ impl CheckAttrVisitor<'_> {
14501465

14511466
/// Helper function for checking that the provided attribute is only applied to a function or
14521467
/// method.
1453-
fn check_applied_to_fn_or_method(&self, attr: &Attribute, span: Span, target: Target) -> bool {
1468+
fn check_applied_to_fn_or_method(
1469+
&self,
1470+
hir_id: HirId,
1471+
attr: &Attribute,
1472+
span: Span,
1473+
target: Target,
1474+
) -> bool {
14541475
let is_function = matches!(target, Target::Fn | Target::Method(..));
14551476
if !is_function {
14561477
self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
14571478
attr_span: attr.span,
14581479
defn_span: span,
1480+
on_crate: hir_id == CRATE_HIR_ID,
14591481
});
14601482
false
14611483
} else {
@@ -1467,17 +1489,24 @@ impl CheckAttrVisitor<'_> {
14671489
/// or method.
14681490
fn check_rustc_lint_query_instability(
14691491
&self,
1492+
hir_id: HirId,
14701493
attr: &Attribute,
14711494
span: Span,
14721495
target: Target,
14731496
) -> bool {
1474-
self.check_applied_to_fn_or_method(attr, span, target)
1497+
self.check_applied_to_fn_or_method(hir_id, attr, span, target)
14751498
}
14761499

14771500
/// Checks that the `#[rustc_lint_diagnostics]` attribute is only applied to a function or
14781501
/// method.
1479-
fn check_rustc_lint_diagnostics(&self, attr: &Attribute, span: Span, target: Target) -> bool {
1480-
self.check_applied_to_fn_or_method(attr, span, target)
1502+
fn check_rustc_lint_diagnostics(
1503+
&self,
1504+
hir_id: HirId,
1505+
attr: &Attribute,
1506+
span: Span,
1507+
target: Target,
1508+
) -> bool {
1509+
self.check_applied_to_fn_or_method(hir_id, attr, span, target)
14811510
}
14821511

14831512
/// Checks that the `#[rustc_lint_opt_ty]` attribute is only applied to a struct.

compiler/rustc_passes/src/errors.rs

+3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ pub struct AttrShouldBeAppliedToFn {
8181
pub attr_span: Span,
8282
#[label]
8383
pub defn_span: Span,
84+
pub on_crate: bool,
8485
}
8586

8687
#[derive(Diagnostic)]
@@ -97,6 +98,7 @@ pub struct TrackedCallerWrongLocation {
9798
pub attr_span: Span,
9899
#[label]
99100
pub defn_span: Span,
101+
pub on_crate: bool,
100102
}
101103

102104
#[derive(Diagnostic)]
@@ -367,6 +369,7 @@ pub struct MustNotSuspend {
367369
pub struct Cold {
368370
#[label]
369371
pub span: Span,
372+
pub on_crate: bool,
370373
}
371374

372375
#[derive(LintDiagnostic)]

compiler/rustc_resolve/src/diagnostics.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,12 @@ impl<'a> Resolver<'a> {
241241
));
242242

243243
err.span_label(span, format!("`{}` re{} here", name, new_participle));
244-
err.span_label(
245-
self.session.source_map().guess_head_span(old_binding.span),
246-
format!("previous {} of the {} `{}` here", old_noun, old_kind, name),
247-
);
244+
if !old_binding.span.is_dummy() && old_binding.span != span {
245+
err.span_label(
246+
self.session.source_map().guess_head_span(old_binding.span),
247+
format!("previous {} of the {} `{}` here", old_noun, old_kind, name),
248+
);
249+
}
248250

249251
// See https://github.com/rust-lang/rust/issues/32354
250252
use NameBindingKind::Import;

compiler/rustc_resolve/src/late/diagnostics.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -806,14 +806,16 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
806806
err.code(rustc_errors::error_code!(E0411));
807807
err.span_label(span, "`Self` is only available in impls, traits, and type definitions");
808808
if let Some(item_kind) = self.diagnostic_metadata.current_item {
809-
err.span_label(
810-
item_kind.ident.span,
811-
format!(
812-
"`Self` not allowed in {} {}",
813-
item_kind.kind.article(),
814-
item_kind.kind.descr()
815-
),
816-
);
809+
if !item_kind.ident.span.is_dummy() {
810+
err.span_label(
811+
item_kind.ident.span,
812+
format!(
813+
"`Self` not allowed in {} {}",
814+
item_kind.kind.article(),
815+
item_kind.kind.descr()
816+
),
817+
);
818+
}
817819
}
818820
true
819821
}

src/test/ui/asm/naked-invalid-attr.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ error: attribute should be applied to a function definition
3636
--> $DIR/naked-invalid-attr.rs:5:1
3737
|
3838
LL | #![naked]
39-
| ^^^^^^^^^
39+
| ^^^^^^^^^ cannot be applied to crates
4040

4141
error: aborting due to 5 previous errors
4242

src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -110,19 +110,19 @@ error: attribute should be applied to an `extern crate` item
110110
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:25:1
111111
|
112112
LL | #![no_link]
113-
| ^^^^^^^^^^^
113+
| ^^^^^^^^^^^ not an `extern crate` item
114114

115115
error: attribute should be applied to a free function, impl method or static
116116
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:27:1
117117
|
118118
LL | #![export_name = "2200"]
119-
| ^^^^^^^^^^^^^^^^^^^^^^^^
119+
| ^^^^^^^^^^^^^^^^^^^^^^^^ not a free function, impl method or static
120120

121121
error[E0518]: attribute should be applied to function or closure
122122
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:29:1
123123
|
124124
LL | #![inline]
125-
| ^^^^^^^^^^
125+
| ^^^^^^^^^^ not a function or closure
126126

127127
error: `macro_export` attribute cannot be used at crate level
128128
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:12:1

src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//~ NOTE not a function
22
//~| NOTE not a foreign function or static
3-
//~| NOTE not a function or static
3+
//~| NOTE cannot be applied to crates
44
//~| NOTE not an `extern` block
55
// This test enumerates as many compiler-builtin ungated attributes as
66
// possible (that is, all the mutually compatible ones), and checks

src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -403,31 +403,31 @@ warning: attribute should be applied to a function definition
403403
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1
404404
|
405405
LL | #![cold]
406-
| ^^^^^^^^
406+
| ^^^^^^^^ cannot be applied to crates
407407
|
408408
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
409409

410410
warning: attribute should be applied to an `extern` block with non-Rust ABI
411411
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:64:1
412412
|
413413
LL | #![link()]
414-
| ^^^^^^^^^^
414+
| ^^^^^^^^^^ not an `extern` block
415415
|
416416
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
417417

418418
warning: attribute should be applied to a foreign function or static
419419
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:66:1
420420
|
421421
LL | #![link_name = "1900"]
422-
| ^^^^^^^^^^^^^^^^^^^^^^
422+
| ^^^^^^^^^^^^^^^^^^^^^^ not a foreign function or static
423423
|
424424
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
425425

426426
warning: attribute should be applied to a function or static
427427
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:69:1
428428
|
429429
LL | #![link_section = "1800"]
430-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
430+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not a function or static
431431
|
432432
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
433433

src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr

+1-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ error[E0428]: the name `A` is defined multiple times
22
--> $DIR/issue-69396-const-no-type-in-macro.rs:4:13
33
|
44
LL | const A = "A".$fn();
5-
| ^^^^^^^^^^^^^^^^^^^^
6-
| |
7-
| `A` redefined here
8-
| previous definition of the value `A` here
5+
| ^^^^^^^^^^^^^^^^^^^^ `A` redefined here
96
...
107
LL | / suite! {
118
LL | | len;

0 commit comments

Comments
 (0)