about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaul Faria <Nashenas88@gmail.com>2015-06-15 14:49:04 -0400
committerPaul Faria <Nashenas88@gmail.com>2015-06-19 21:08:53 -0400
commit973da22ea3d8074d8ce1214f7a356e96efe4131a (patch)
tree22a5761fca36951803a55f9b98b350e6e692e793
parentc8a0b0eece9e3ac852413bc715f788261a217e74 (diff)
downloadrust-973da22ea3d8074d8ce1214f7a356e96efe4131a.tar.gz
rust-973da22ea3d8074d8ce1214f7a356e96efe4131a.zip
Wrapped inferred context changes in a probe, handle fnOnce trait require error with a fallback, renamed variable to something clearer
-rw-r--r--src/librustc_typeck/check/method/suggest.rs63
1 files changed, 36 insertions, 27 deletions
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 2abb53e55f6..a61985d3a00 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -73,40 +73,49 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                         // snippet
                     };
 
-                    fn span_stored_function() {
-                        cx.sess.span_note(span, &format!("use `({0}.{1})(...)` if you meant to call \
-                                                          the function stored in the `{1}` field",
-                                                         expr_string, item_name));
-                    }
+                    macro_rules! span_stored_function {
+                        () => {
+                            cx.sess.span_note(span,
+                                              &format!("use `({0}.{1})(...)` if you meant to call \
+                                                        the function stored in the `{1}` field",
+                                                       expr_string, item_name));
+                        }
+                    };
 
-                    fn span_did_you_mean() {
-                        cx.sess.span_note(span, &format!("did you mean to write `{0}.{1}`?",
-                                                         expr_string, item_name));
-                    }
+                    macro_rules! span_did_you_mean {
+                        () => {
+                            cx.sess.span_note(span, &format!("did you mean to write `{0}.{1}`?",
+                                                             expr_string, item_name));
+                        }
+                    };
 
                     // Determine if the field can be used as a function in some way
                     let field_ty = ty::lookup_field_type(cx, did, field.id, substs);
                     if let Ok(fn_once_trait_did) = cx.lang_items.require(FnOnceTraitLangItem) {
-                        let fn_once_substs = Substs::new_trait(vec![fcx.inh.infcx.next_ty_var()],
-                                                               Vec::new(),
-                                                               field_ty);
-                        let trait_ref = ty::TraitRef::new(fn_once_trait_did,
-                                                          cx.mk_substs(fn_once_substs));
-                        let poly_trait_ref = trait_ref.to_poly_trait_ref();
-                        let obligation = Obligation::misc(span,
-                                                          fcx.body_id,
-                                                          poly_trait_ref.as_predicate());
-                        let mut selcx = SelectionContext::new(fcx.infcx(), fcx);
-
-                        if selcx.evaluate_obligation(&obligation) {
-                            span_stored_function();
-                        } else {
-                            span_did_you_mean();
-                        }
+                        let infcx = fcx.infcx();
+                        infcx.probe(|_| {
+                            let fn_once_substs = Substs::new_trait(vec![infcx.next_ty_var()],
+                                                                   Vec::new(),
+                                                                   field_ty);
+                            let trait_ref = ty::TraitRef::new(fn_once_trait_did,
+                                                              cx.mk_substs(fn_once_substs));
+                            let poly_trait_ref = trait_ref.to_poly_trait_ref();
+                            let obligation = Obligation::misc(span,
+                                                              fcx.body_id,
+                                                              poly_trait_ref.as_predicate());
+                            let mut selcx = SelectionContext::new(infcx, fcx);
+
+                            if selcx.evaluate_obligation(&obligation) {
+                                span_stored_function!();
+                            } else {
+                                span_did_you_mean!();
+                            }
+                        });
                     } else {
                         match field_ty.sty {
-                            ty::TyClosure(_,_) | ty::TyFnPtr(_,_) => span_stored_function(),
-                            _ => span_did_you_mean(),
+                            // fallback to matching a closure or function pointer
+                            ty::TyClosure(_,_) | ty::TyBareFn(None,_) => span_stored_function!(),
+                            _ => span_did_you_mean!(),
                         }
                     }
                 }