@@ -7,7 +7,7 @@ use rustc_macros::Subdiagnostic;
77use rustc_parse:: parser:: { Parser , Recovery , token_descr} ;
88use rustc_session:: parse:: ParseSess ;
99use rustc_span:: source_map:: SourceMap ;
10- use rustc_span:: { ErrorGuaranteed , Ident , Span } ;
10+ use rustc_span:: { DUMMY_SP , ErrorGuaranteed , Ident , Span } ;
1111use tracing:: debug;
1212
1313use super :: macro_rules:: { MacroRule , NoopTracker , parser_from_cx} ;
@@ -25,6 +25,12 @@ pub(super) fn failed_to_match_macro(
2525 rules : & [ MacroRule ] ,
2626) -> ( Span , ErrorGuaranteed ) {
2727 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+
2834 // An error occurred, try the expansion again, tracking the expansion closely for better
2935 // diagnostics.
3036 let mut tracker = CollectTrackerAndEmitter :: new ( psess. dcx ( ) , sp) ;
@@ -47,15 +53,27 @@ pub(super) fn failed_to_match_macro(
4753
4854 let Some ( BestFailure { token, msg : label, remaining_matcher, .. } ) = tracker. best_failure
4955 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+ }
5068 return ( sp, psess. dcx ( ) . span_delayed_bug ( sp, "failed to match a macro" ) ) ;
5169 } ;
5270
5371 let span = token. span . substitute_dummy ( sp) ;
5472
5573 let mut err = psess. dcx ( ) . struct_span_err ( span, parse_failure_msg ( & token, None ) ) ;
5674 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" ) ;
5977 }
6078
6179 annotate_doc_comment ( & mut err, psess. source_map ( ) , span) ;
0 commit comments