mirror of
https://github.com/rust-lang/rust
synced 2024-10-06 16:51:35 +00:00
Handle error case safely with a fallback
This commit is contained in:
parent
0230a530ce
commit
c8a0b0eece
|
@ -73,33 +73,42 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
// snippet
|
// snippet
|
||||||
};
|
};
|
||||||
|
|
||||||
// Determine if the field can be used as a function in some way
|
fn span_stored_function() {
|
||||||
let fn_once_trait_did = match cx.lang_items.require(FnOnceTraitLangItem) {
|
cx.sess.span_note(span, &format!("use `({0}.{1})(...)` if you meant to call \
|
||||||
Ok(trait_did) => trait_did,
|
the function stored in the `{1}` field",
|
||||||
Err(err) => cx.sess.fatal(&err[..])
|
expr_string, item_name));
|
||||||
};
|
}
|
||||||
|
|
||||||
let field_ty = ty::lookup_field_type(cx, did, field.id, substs);
|
fn span_did_you_mean() {
|
||||||
let field_ty_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(field_ty_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) {
|
|
||||||
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));
|
|
||||||
} else {
|
|
||||||
cx.sess.span_note(span, &format!("did you mean to write `{0}.{1}`?",
|
cx.sess.span_note(span, &format!("did you mean to write `{0}.{1}`?",
|
||||||
expr_string, item_name));
|
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();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
match field_ty.sty {
|
||||||
|
ty::TyClosure(_,_) | ty::TyFnPtr(_,_) => span_stored_function(),
|
||||||
|
_ => span_did_you_mean(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue