Skip to content

Commit c8a0b0e

Browse files
committed
Handle error case safely with a fallback
1 parent 0230a53 commit c8a0b0e

File tree

1 file changed

+32
-23
lines changed

1 file changed

+32
-23
lines changed

src/librustc_typeck/check/method/suggest.rs

+32-23
Original file line numberDiff line numberDiff line change
@@ -73,33 +73,42 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
7373
// snippet
7474
};
7575

76-
// Determine if the field can be used as a function in some way
77-
let fn_once_trait_did = match cx.lang_items.require(FnOnceTraitLangItem) {
78-
Ok(trait_did) => trait_did,
79-
Err(err) => cx.sess.fatal(&err[..])
80-
};
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+
}
8181

82-
let field_ty = ty::lookup_field_type(cx, did, field.id, substs);
83-
let field_ty_substs = Substs::new_trait(vec![fcx.inh.infcx.next_ty_var()],
84-
Vec::new(),
85-
field_ty);
86-
let trait_ref = ty::TraitRef::new(fn_once_trait_did,
87-
cx.mk_substs(field_ty_substs));
88-
let poly_trait_ref = trait_ref.to_poly_trait_ref();
89-
let obligation = Obligation::misc(span,
90-
fcx.body_id,
91-
poly_trait_ref.as_predicate());
92-
let mut selcx = SelectionContext::new(fcx.infcx(), fcx);
93-
94-
if selcx.evaluate_obligation(&obligation) {
95-
cx.sess.span_note(span,
96-
&format!("use `({0}.{1})(...)` if you meant to call the \
97-
function stored in the `{1}` field",
98-
expr_string, item_name));
99-
} else {
82+
fn span_did_you_mean() {
10083
cx.sess.span_note(span, &format!("did you mean to write `{0}.{1}`?",
10184
expr_string, item_name));
10285
}
86+
87+
// Determine if the field can be used as a function in some way
88+
let field_ty = ty::lookup_field_type(cx, did, field.id, substs);
89+
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+
}
106+
} else {
107+
match field_ty.sty {
108+
ty::TyClosure(_,_) | ty::TyFnPtr(_,_) => span_stored_function(),
109+
_ => span_did_you_mean(),
110+
}
111+
}
103112
}
104113
}
105114

0 commit comments

Comments
 (0)