@@ -73,40 +73,49 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
7373 // snippet
7474 } ;
7575
76- fn span_stored_function ( ) {
77- cx. sess . span_note ( span, & format ! ( "use `({0}.{1})(...)` if you meant to call \
78- the function stored in the `{1}` field",
79- expr_string, item_name) ) ;
80- }
76+ macro_rules! span_stored_function {
77+ ( ) => {
78+ cx. sess. span_note( span,
79+ & format!( "use `({0}.{1})(...)` if you meant to call \
80+ the function stored in the `{1}` field",
81+ expr_string, item_name) ) ;
82+ }
83+ } ;
8184
82- fn span_did_you_mean ( ) {
83- cx. sess . span_note ( span, & format ! ( "did you mean to write `{0}.{1}`?" ,
84- expr_string, item_name) ) ;
85- }
85+ macro_rules! span_did_you_mean {
86+ ( ) => {
87+ cx. sess. span_note( span, & format!( "did you mean to write `{0}.{1}`?" ,
88+ expr_string, item_name) ) ;
89+ }
90+ } ;
8691
8792 // Determine if the field can be used as a function in some way
8893 let field_ty = ty:: lookup_field_type ( cx, did, field. id , substs) ;
8994 if let Ok ( fn_once_trait_did) = cx. lang_items . require ( FnOnceTraitLangItem ) {
90- let fn_once_substs = Substs :: new_trait ( vec ! [ fcx. inh. infcx. next_ty_var( ) ] ,
91- Vec :: new ( ) ,
92- field_ty) ;
93- let trait_ref = ty:: TraitRef :: new ( fn_once_trait_did,
94- cx. mk_substs ( fn_once_substs) ) ;
95- let poly_trait_ref = trait_ref. to_poly_trait_ref ( ) ;
96- let obligation = Obligation :: misc ( span,
97- fcx. body_id ,
98- poly_trait_ref. as_predicate ( ) ) ;
99- let mut selcx = SelectionContext :: new ( fcx. infcx ( ) , fcx) ;
100-
101- if selcx. evaluate_obligation ( & obligation) {
102- span_stored_function ( ) ;
103- } else {
104- span_did_you_mean ( ) ;
105- }
95+ let infcx = fcx. infcx ( ) ;
96+ infcx. probe ( |_| {
97+ let fn_once_substs = Substs :: new_trait ( vec ! [ infcx. next_ty_var( ) ] ,
98+ Vec :: new ( ) ,
99+ field_ty) ;
100+ let trait_ref = ty:: TraitRef :: new ( fn_once_trait_did,
101+ cx. mk_substs ( fn_once_substs) ) ;
102+ let poly_trait_ref = trait_ref. to_poly_trait_ref ( ) ;
103+ let obligation = Obligation :: misc ( span,
104+ fcx. body_id ,
105+ poly_trait_ref. as_predicate ( ) ) ;
106+ let mut selcx = SelectionContext :: new ( infcx, fcx) ;
107+
108+ if selcx. evaluate_obligation ( & obligation) {
109+ span_stored_function ! ( ) ;
110+ } else {
111+ span_did_you_mean ! ( ) ;
112+ }
113+ } ) ;
106114 } else {
107115 match field_ty. sty {
108- ty:: TyClosure ( _, _) | ty:: TyFnPtr ( _, _) => span_stored_function ( ) ,
109- _ => span_did_you_mean ( ) ,
116+ // fallback to matching a closure or function pointer
117+ ty:: TyClosure ( _, _) | ty:: TyBareFn ( None , _) => span_stored_function ! ( ) ,
118+ _ => span_did_you_mean ! ( ) ,
110119 }
111120 }
112121 }
0 commit comments