Fix ICE when calling non-functions within closures

The visitor for walking function bodies did not previously properly
handle error-cases for function calls. These are now ignored,
preventing the panic.
This commit is contained in:
varkor 2017-12-17 01:53:30 +00:00
parent a3a7203e2c
commit a4210ef437
2 changed files with 34 additions and 17 deletions

View File

@ -558,24 +558,27 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
}
ty::TyError => { }
_ => {
let def_id = self.mc.tables.type_dependent_defs()[call.hir_id].def_id();
let call_scope = region::Scope::Node(call.hir_id.local_id);
match OverloadedCallType::from_method_id(self.tcx(), def_id) {
FnMutOverloadedCall => {
let call_scope_r = self.tcx().mk_region(ty::ReScope(call_scope));
self.borrow_expr(callee,
call_scope_r,
ty::MutBorrow,
ClosureInvocation);
let type_dependent_defs = self.mc.tables.type_dependent_defs();
if !type_dependent_defs.contains_key(call.hir_id) {
let def_id = type_dependent_defs[call.hir_id].def_id();
let call_scope = region::Scope::Node(call.hir_id.local_id);
match OverloadedCallType::from_method_id(self.tcx(), def_id) {
FnMutOverloadedCall => {
let call_scope_r = self.tcx().mk_region(ty::ReScope(call_scope));
self.borrow_expr(callee,
call_scope_r,
ty::MutBorrow,
ClosureInvocation);
}
FnOverloadedCall => {
let call_scope_r = self.tcx().mk_region(ty::ReScope(call_scope));
self.borrow_expr(callee,
call_scope_r,
ty::ImmBorrow,
ClosureInvocation);
}
FnOnceOverloadedCall => {self.consume_expr(callee)},
}
FnOverloadedCall => {
let call_scope_r = self.tcx().mk_region(ty::ReScope(call_scope));
self.borrow_expr(callee,
call_scope_r,
ty::ImmBorrow,
ClosureInvocation);
}
FnOnceOverloadedCall => self.consume_expr(callee),
}
}
}

View File

@ -0,0 +1,14 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn main() {
struct Foo;
(1 .. 2).find(|_| Foo(0) == 0); //~ ERROR expected function, found `main::Foo`
}