@@ -7,7 +7,7 @@ use rustc_macros::Subdiagnostic;
7
7
use rustc_parse:: parser:: { Parser , Recovery , token_descr} ;
8
8
use rustc_session:: parse:: ParseSess ;
9
9
use rustc_span:: source_map:: SourceMap ;
10
- use rustc_span:: { ErrorGuaranteed , Ident , Span } ;
10
+ use rustc_span:: { DUMMY_SP , ErrorGuaranteed , Ident , Span } ;
11
11
use tracing:: debug;
12
12
13
13
use super :: macro_rules:: { MacroRule , NoopTracker , parser_from_cx} ;
@@ -25,6 +25,12 @@ pub(super) fn failed_to_match_macro(
25
25
rules : & [ MacroRule ] ,
26
26
) -> ( Span , ErrorGuaranteed ) {
27
27
debug ! ( "failed to match macro" ) ;
28
+ let def_head_span = if !def_span. is_dummy ( ) && !psess. source_map ( ) . is_imported ( def_span) {
29
+ psess. source_map ( ) . guess_head_span ( def_span)
30
+ } else {
31
+ DUMMY_SP
32
+ } ;
33
+
28
34
// An error occurred, try the expansion again, tracking the expansion closely for better
29
35
// diagnostics.
30
36
let mut tracker = CollectTrackerAndEmitter :: new ( psess. dcx ( ) , sp) ;
@@ -47,15 +53,22 @@ pub(super) fn failed_to_match_macro(
47
53
48
54
let Some ( BestFailure { token, msg : label, remaining_matcher, .. } ) = tracker. best_failure
49
55
else {
56
+ if !rules. iter ( ) . any ( |rule| matches ! ( rule, MacroRule :: Func { .. } ) ) {
57
+ let mut err = psess. dcx ( ) . struct_span_err ( sp, "invoked macro has no invocation rules" ) ;
58
+ if !def_head_span. is_dummy ( ) {
59
+ err. span_label ( def_head_span, "this macro has no rules to invoke" ) ;
60
+ }
61
+ return ( sp, err. emit ( ) ) ;
62
+ }
50
63
return ( sp, psess. dcx ( ) . span_delayed_bug ( sp, "failed to match a macro" ) ) ;
51
64
} ;
52
65
53
66
let span = token. span . substitute_dummy ( sp) ;
54
67
55
68
let mut err = psess. dcx ( ) . struct_span_err ( span, parse_failure_msg ( & token, None ) ) ;
56
69
err. span_label ( span, label) ;
57
- if !def_span . is_dummy ( ) && !psess . source_map ( ) . is_imported ( def_span ) {
58
- err. span_label ( psess . source_map ( ) . guess_head_span ( def_span ) , "when calling this macro" ) ;
70
+ if !def_head_span . is_dummy ( ) {
71
+ err. span_label ( def_head_span , "when calling this macro" ) ;
59
72
}
60
73
61
74
annotate_doc_comment ( & mut err, psess. source_map ( ) , span) ;
0 commit comments