]> git.lizzy.rs Git - rust.git/commitdiff
Fix ICE when calling non-functions within closures
authorvarkor <github@varkor.com>
Sun, 17 Dec 2017 01:53:30 +0000 (01:53 +0000)
committervarkor <github@varkor.com>
Mon, 18 Dec 2017 15:51:44 +0000 (15:51 +0000)
The visitor for walking function bodies did not previously properly
handle error-cases for function calls. These are now ignored,
preventing the panic.

src/librustc/middle/expr_use_visitor.rs
src/test/compile-fail/issue-46771.rs [new file with mode: 0644]

index 9018b9fe590b2e8bd53035f488ea937284070f8f..0bce2ac0131a97be2f8a32f76bf2175de56cbd1b 100644 (file)
@@ -558,24 +558,27 @@ fn walk_callee(&mut self, call: &hir::Expr, callee: &hir::Expr) {
             }
             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);
+                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)},
                     }
-                    FnOnceOverloadedCall => self.consume_expr(callee),
                 }
             }
         }
diff --git a/src/test/compile-fail/issue-46771.rs b/src/test/compile-fail/issue-46771.rs
new file mode 100644 (file)
index 0000000..e167289
--- /dev/null
@@ -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`
+}
\ No newline at end of file