about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2017-12-22 02:50:47 +0800
committerGitHub <noreply@github.com>2017-12-22 02:50:47 +0800
commit44670448b2449fc63756ab1c82bbf104d79a050a (patch)
tree08a5bd13a0d046cad219beecb08b4c8ba07786ce
parent71c6d23612e808dc87cfe55f40e95bdc66af1806 (diff)
parent5741dcd1f88a692ad7913c1c27b2461a0509e7f4 (diff)
downloadrust-44670448b2449fc63756ab1c82bbf104d79a050a.tar.gz
rust-44670448b2449fc63756ab1c82bbf104d79a050a.zip
Rollup merge of #46780 - varkor:contrib-5, r=arielb1
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 fixes #46771.
-rw-r--r--src/librustc/middle/expr_use_visitor.rs39
-rw-r--r--src/test/compile-fail/issue-46771.rs14
2 files changed, 36 insertions, 17 deletions
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 9018b9fe590..3bcde93fde5 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -558,24 +558,29 @@ 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);
-                    }
-                    FnOverloadedCall => {
-                        let call_scope_r = self.tcx().mk_region(ty::ReScope(call_scope));
-                        self.borrow_expr(callee,
-                                         call_scope_r,
-                                         ty::ImmBorrow,
-                                         ClosureInvocation);
+                if let Some(def) = self.mc.tables.type_dependent_defs().get(call.hir_id) {
+                    let def_id = def.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),
                     }
-                    FnOnceOverloadedCall => self.consume_expr(callee),
+                } else {
+                    self.tcx().sess.delay_span_bug(call.span,
+                                                   "no type-dependent def for overloaded call");
                 }
             }
         }
diff --git a/src/test/compile-fail/issue-46771.rs b/src/test/compile-fail/issue-46771.rs
new file mode 100644
index 00000000000..f8bcd8861f3
--- /dev/null
+++ b/src/test/compile-fail/issue-46771.rs
@@ -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`
+}