// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use hir::{self, map, Local, Pat, Body};
+use hir::{self, Local, Pat, Body};
use hir::intravisit::{self, Visitor, NestedVisitorMap};
use infer::InferCtxt;
use infer::type_variable::TypeVariableOrigin;
}
}
- pub fn need_type_info(&self, body_id: hir::BodyId, span: Span, ty: Ty<'tcx>) {
+ pub fn need_type_info(&self, body_id: Option<hir::BodyId>, span: Span, ty: Ty<'tcx>) {
let ty = self.resolve_type_vars_if_possible(&ty);
let name = self.extract_type_name(&ty);
found_arg_pattern: None,
};
- // #40294: cause.body_id can also be a fn declaration.
- // Currently, if it's anything other than NodeExpr, we just ignore it
- match self.tcx.hir.find(body_id.node_id) {
- Some(map::NodeExpr(expr)) => local_visitor.visit_expr(expr),
- _ => ()
+ if let Some(body_id) = body_id {
+ let expr = self.tcx.hir.expect_expr(body_id.node_id);
+ local_visitor.visit_expr(expr);
}
if let Some(pattern) = local_visitor.found_arg_pattern {
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
pub fn report_fulfillment_errors(&self,
- errors: &Vec<FulfillmentError<'tcx>>) {
+ errors: &Vec<FulfillmentError<'tcx>>,
+ body_id: Option<hir::BodyId>) {
#[derive(Debug)]
struct ErrorDescriptor<'tcx> {
predicate: ty::Predicate<'tcx>,
for (error, suppressed) in errors.iter().zip(is_suppressed) {
if !suppressed {
- self.report_fulfillment_error(error);
+ self.report_fulfillment_error(error, body_id);
}
}
}
false
}
- fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) {
+ fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>,
+ body_id: Option<hir::BodyId>) {
debug!("report_fulfillment_errors({:?})", error);
match error.code {
FulfillmentErrorCode::CodeSelectionError(ref e) => {
self.report_projection_error(&error.obligation, e);
}
FulfillmentErrorCode::CodeAmbiguity => {
- self.maybe_report_ambiguity(&error.obligation);
+ self.maybe_report_ambiguity(&error.obligation, body_id);
}
FulfillmentErrorCode::CodeSubtypeError(ref expected_found, ref err) => {
self.report_mismatched_types(&error.obligation.cause,
}
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
- fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) {
+ fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>,
+ body_id: Option<hir::BodyId>) {
// Unable to successfully determine, probably means
// insufficient type information, but could mean
// ambiguous impls. The latter *ought* to be a
// coherence violation, so we don't report it here.
let predicate = self.resolve_type_vars_if_possible(&obligation.predicate);
- let body_id = hir::BodyId { node_id: obligation.cause.body_id };
let span = obligation.cause.span;
debug!("maybe_report_ambiguity(predicate={:?}, obligation={:?})",
let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder();
// both must be type variables, or the other would've been instantiated
assert!(a.is_ty_var() && b.is_ty_var());
- self.need_type_info(hir::BodyId { node_id: obligation.cause.body_id },
+ self.need_type_info(body_id,
obligation.cause.span,
a);
}
) {
Ok(predicates) => predicates,
Err(errors) => {
- infcx.report_fulfillment_errors(&errors);
+ infcx.report_fulfillment_errors(&errors, None);
// An unnormalized env is better than nothing.
return elaborated_env;
}
tcx.require_lang_item(lang_items::SyncTraitLangItem),
cause);
if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
- infcx.report_fulfillment_errors(&err);
+ infcx.report_fulfillment_errors(&err, None);
}
});
}
// Check that all obligations are satisfied by the implementation's
// version.
if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) {
- infcx.report_fulfillment_errors(errors);
+ infcx.report_fulfillment_errors(errors, None);
return Err(ErrorReported);
}
// Check that all obligations are satisfied by the implementation's
// version.
if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) {
- infcx.report_fulfillment_errors(errors);
+ infcx.report_fulfillment_errors(errors, None);
return;
}
if let Err(ref errors) = fulfillment_cx.select_all_or_error(&infcx) {
// this could be reached when we get lazy normalization
- infcx.report_fulfillment_errors(errors);
+ infcx.report_fulfillment_errors(errors, None);
return Err(ErrorReported);
}
/// environment is for an item or something where the "callee" is
/// not clear.
implicit_region_bound: Option<ty::Region<'tcx>>,
+
+ body_id: Option<hir::BodyId>,
}
impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> {
deferred_cast_checks: RefCell::new(Vec::new()),
anon_types: RefCell::new(NodeMap()),
implicit_region_bound,
+ body_id,
}
}
match fulfillment_cx.select_all_or_error(self) {
Ok(()) => { }
- Err(errors) => { self.report_fulfillment_errors(&errors); }
+ Err(errors) => { self.report_fulfillment_errors(&errors, self.inh.body_id); }
}
}
fn select_obligations_where_possible(&self) {
match self.fulfillment_cx.borrow_mut().select_where_possible(self) {
Ok(()) => { }
- Err(errors) => { self.report_fulfillment_errors(&errors); }
+ Err(errors) => { self.report_fulfillment_errors(&errors, self.inh.body_id); }
}
}
fn report_error(&self, t: Ty<'tcx>) {
if !self.tcx.sess.has_errors() {
- self.infcx.need_type_info(self.body.id(), self.span.to_span(&self.tcx), t);
+ self.infcx.need_type_info(Some(self.body.id()), self.span.to_span(&self.tcx), t);
}
}
}
// Check that all transitive obligations are satisfied.
if let Err(errors) = fulfill_cx.select_all_or_error(&infcx) {
- infcx.report_fulfillment_errors(&errors);
+ infcx.report_fulfillment_errors(&errors, None);
}
// Finally, resolve all regions.
match fulfill_cx.select_all_or_error(infcx) {
Ok(()) => true,
Err(errors) => {
- infcx.report_fulfillment_errors(&errors);
+ infcx.report_fulfillment_errors(&errors, None);
false
}
}
}
fn main() {
- let ex = |x| {
- let_(add(x,x), |y| { //~ ERROR type annotations needed
+ let ex = |x| { //~ ERROR type annotations needed
+ let_(add(x,x), |y| {
let_(add(x, x), |x|x)})};
}