Skip to content

Commit 9431520

Browse files
authored
Rollup merge of #98882 - compiler-errors:explain-doc-comments-in-macros, r=davidtwco
explain doc comments in macros a bit Open to suggestions on improving this... macro parsing is very foreign to me. Should we have a structured suggestion to turn them into their regular non-doc comments? Fixes #92846 Fixes #97850
2 parents 2682b88 + d2e5a92 commit 9431520

File tree

5 files changed

+50
-6
lines changed

5 files changed

+50
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
expand-explain-doc-comment-outer =
2+
outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match
3+
4+
expand-explain-doc-comment-inner =
5+
inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match

compiler/rustc_error_messages/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ pub use unic_langid::{langid, LanguageIdentifier};
3333
fluent_messages! {
3434
borrowck => "../locales/en-US/borrowck.ftl",
3535
builtin_macros => "../locales/en-US/builtin_macros.ftl",
36+
const_eval => "../locales/en-US/const_eval.ftl",
37+
expand => "../locales/en-US/expand.ftl",
3638
lint => "../locales/en-US/lint.ftl",
3739
parser => "../locales/en-US/parser.ftl",
3840
privacy => "../locales/en-US/privacy.ftl",
3941
typeck => "../locales/en-US/typeck.ftl",
40-
const_eval => "../locales/en-US/const_eval.ftl",
4142
}
4243

4344
pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES};

compiler/rustc_expand/src/mbe/macro_rules.rs

+35-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_ast::{NodeId, DUMMY_NODE_ID};
1414
use rustc_ast_pretty::pprust;
1515
use rustc_attr::{self as attr, TransparencyError};
1616
use rustc_data_structures::fx::FxHashMap;
17-
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder};
17+
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
1818
use rustc_feature::Features;
1919
use rustc_lint_defs::builtin::{
2020
RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
@@ -25,6 +25,7 @@ use rustc_session::parse::ParseSess;
2525
use rustc_session::Session;
2626
use rustc_span::edition::Edition;
2727
use rustc_span::hygiene::Transparency;
28+
use rustc_span::source_map::SourceMap;
2829
use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent};
2930
use rustc_span::Span;
3031

@@ -345,7 +346,7 @@ fn expand_macro<'cx>(
345346
if !def_span.is_dummy() && !cx.source_map().is_imported(def_span) {
346347
err.span_label(cx.source_map().guess_head_span(def_span), "when calling this macro");
347348
}
348-
349+
annotate_doc_comment(&mut err, sess.source_map(), span);
349350
// Check whether there's a missing comma in this macro call, like `println!("{}" a);`
350351
if let Some((arg, comma_span)) = arg.add_comma() {
351352
for lhs in lhses {
@@ -453,7 +454,10 @@ pub fn compile_declarative_macro(
453454
Failure(token, msg) => {
454455
let s = parse_failure_msg(&token);
455456
let sp = token.span.substitute_dummy(def.span);
456-
sess.parse_sess.span_diagnostic.struct_span_err(sp, &s).span_label(sp, msg).emit();
457+
let mut err = sess.parse_sess.span_diagnostic.struct_span_err(sp, &s);
458+
err.span_label(sp, msg);
459+
annotate_doc_comment(&mut err, sess.source_map(), sp);
460+
err.emit();
457461
return dummy_syn_ext();
458462
}
459463
Error(sp, msg) => {
@@ -590,6 +594,34 @@ pub fn compile_declarative_macro(
590594
(mk_syn_ext(expander), rule_spans)
591595
}
592596

597+
#[derive(SessionSubdiagnostic)]
598+
enum ExplainDocComment {
599+
#[label(expand::explain_doc_comment_inner)]
600+
Inner {
601+
#[primary_span]
602+
span: Span,
603+
},
604+
#[label(expand::explain_doc_comment_outer)]
605+
Outer {
606+
#[primary_span]
607+
span: Span,
608+
},
609+
}
610+
611+
fn annotate_doc_comment(
612+
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
613+
sm: &SourceMap,
614+
span: Span,
615+
) {
616+
if let Ok(src) = sm.span_to_snippet(span) {
617+
if src.starts_with("///") || src.starts_with("/**") {
618+
err.subdiagnostic(ExplainDocComment::Outer { span });
619+
} else if src.starts_with("//!") || src.starts_with("/*!") {
620+
err.subdiagnostic(ExplainDocComment::Inner { span });
621+
}
622+
}
623+
}
624+
593625
fn check_lhs_nt_follows(sess: &ParseSess, def: &ast::Item, lhs: &mbe::TokenTree) -> bool {
594626
// lhs is going to be like TokenTree::Delimited(...), where the
595627
// entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens.

src/test/ui/parser/macro/macro-doc-comments-1.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ LL | macro_rules! outer {
55
| ------------------ when calling this macro
66
...
77
LL | //! Inner
8-
| ^^^^^^^^^ no rules expected this token in macro call
8+
| ^^^^^^^^^
9+
| |
10+
| no rules expected this token in macro call
11+
| inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match
912

1013
error: aborting due to previous error
1114

src/test/ui/parser/macro/macro-doc-comments-2.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ LL | macro_rules! inner {
55
| ------------------ when calling this macro
66
...
77
LL | /// Outer
8-
| ^^^^^^^^^ no rules expected this token in macro call
8+
| ^^^^^^^^^
9+
| |
10+
| no rules expected this token in macro call
11+
| outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match
912

1013
error: aborting due to previous error
1114

0 commit comments

Comments
 (0)