@@ -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,27 @@ 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
+ // FIXME: we should report this at macro resolution time, as we do for
57
+ // `resolve_macro_cannot_use_as_attr`. We can do that once we track multiple macro kinds for a
58
+ // Def.
59
+ if !rules. iter ( ) . any ( |rule| matches ! ( rule, MacroRule :: Func { .. } ) ) {
60
+ let msg = format ! ( "macro has no rules for function-like invocation `{name}!`" ) ;
61
+ let mut err = psess. dcx ( ) . struct_span_err ( sp, msg) ;
62
+ if !def_head_span. is_dummy ( ) {
63
+ let msg = "this macro has no rules for function-like invocation" ;
64
+ err. span_label ( def_head_span, msg) ;
65
+ }
66
+ return ( sp, err. emit ( ) ) ;
67
+ }
50
68
return ( sp, psess. dcx ( ) . span_delayed_bug ( sp, "failed to match a macro" ) ) ;
51
69
} ;
52
70
53
71
let span = token. span . substitute_dummy ( sp) ;
54
72
55
73
let mut err = psess. dcx ( ) . struct_span_err ( span, parse_failure_msg ( & token, None ) ) ;
56
74
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" ) ;
75
+ if !def_head_span . is_dummy ( ) {
76
+ err. span_label ( def_head_span , "when calling this macro" ) ;
59
77
}
60
78
61
79
annotate_doc_comment ( & mut err, psess. source_map ( ) , span) ;
0 commit comments