about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2014-08-20 09:12:16 -0700
committerPatrick Walton <pcwalton@mimiga.net>2014-08-20 13:16:12 -0700
commit24b089721f2c0e2b25228d3d5d31b5ca70d68070 (patch)
treee8c429cf6f18640dbc6b74a7c7f7ad60c4b77aac
parent3f5d0b5b6cd4994c719d57a778697124348a4c1c (diff)
downloadrust-24b089721f2c0e2b25228d3d5d31b5ca70d68070.tar.gz
rust-24b089721f2c0e2b25228d3d5d31b5ca70d68070.zip
librustc: Fix bogus logic for static calls to unboxed closures in the
expression use visitor.

Closes #16166.
-rw-r--r--src/librustc/middle/expr_use_visitor.rs30
-rw-r--r--src/librustc/middle/ty.rs21
-rw-r--r--src/test/run-pass/unboxed-closures-direct-sugary-call.rs17
3 files changed, 56 insertions, 12 deletions
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 6caf54790d1..20ea2b1fba5 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -130,16 +130,11 @@ impl OverloadedCallType {
 
     fn from_method_id(tcx: &ty::ctxt, method_id: ast::DefId)
                       -> OverloadedCallType {
-        let method_descriptor =
-            match tcx.impl_or_trait_items.borrow_mut().find(&method_id) {
-                Some(&ty::MethodTraitItem(ref method_descriptor)) => {
-                    (*method_descriptor).clone()
-                }
-                None => {
-                    tcx.sess.bug("overloaded call method wasn't in method \
-                                  map")
-                }
-            };
+        let method_descriptor = match ty::impl_or_trait_item(tcx, method_id) {
+            ty::MethodTraitItem(ref method_descriptor) => {
+                (*method_descriptor).clone()
+            }
+        };
         let impl_id = match method_descriptor.container {
             ty::TraitContainer(_) => {
                 tcx.sess.bug("statically resolved overloaded call method \
@@ -157,6 +152,19 @@ impl OverloadedCallType {
         OverloadedCallType::from_trait_id(tcx, trait_ref.def_id)
     }
 
+    fn from_unboxed_closure(tcx: &ty::ctxt, closure_did: ast::DefId)
+                            -> OverloadedCallType {
+        let trait_did =
+            tcx.unboxed_closures
+               .borrow()
+               .find(&closure_did)
+               .expect("OverloadedCallType::from_unboxed_closure: didn't \
+                        find closure id")
+               .kind
+               .trait_did(tcx);
+        OverloadedCallType::from_trait_id(tcx, trait_did)
+    }
+
     fn from_method_origin(tcx: &ty::ctxt, origin: &MethodOrigin)
                           -> OverloadedCallType {
         match *origin {
@@ -164,7 +172,7 @@ impl OverloadedCallType {
                 OverloadedCallType::from_method_id(tcx, def_id)
             }
             MethodStaticUnboxedClosure(def_id) => {
-                OverloadedCallType::from_method_id(tcx, def_id)
+                OverloadedCallType::from_unboxed_closure(tcx, def_id)
             }
             MethodParam(ref method_param) => {
                 OverloadedCallType::from_trait_id(tcx, method_param.trait_id)
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index ae96937757f..4772f6a4ddb 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -19,7 +19,8 @@ use middle::def;
 use middle::dependency_format;
 use middle::freevars::CaptureModeMap;
 use middle::freevars;
-use middle::lang_items::{FnMutTraitLangItem, OpaqueStructLangItem};
+use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem};
+use middle::lang_items::{FnOnceTraitLangItem, OpaqueStructLangItem};
 use middle::lang_items::{TyDescStructLangItem, TyVisitorTraitLangItem};
 use middle::mem_categorization as mc;
 use middle::resolve;
@@ -1205,6 +1206,24 @@ pub enum UnboxedClosureKind {
     FnOnceUnboxedClosureKind,
 }
 
+impl UnboxedClosureKind {
+    pub fn trait_did(&self, cx: &ctxt) -> ast::DefId {
+        let result = match *self {
+            FnUnboxedClosureKind => cx.lang_items.require(FnTraitLangItem),
+            FnMutUnboxedClosureKind => {
+                cx.lang_items.require(FnMutTraitLangItem)
+            }
+            FnOnceUnboxedClosureKind => {
+                cx.lang_items.require(FnOnceTraitLangItem)
+            }
+        };
+        match result {
+            Ok(trait_did) => trait_did,
+            Err(err) => cx.sess.fatal(err.as_slice()),
+        }
+    }
+}
+
 pub fn mk_ctxt(s: Session,
                dm: resolve::DefMap,
                named_region_map: resolve_lifetime::NamedRegionMap,
diff --git a/src/test/run-pass/unboxed-closures-direct-sugary-call.rs b/src/test/run-pass/unboxed-closures-direct-sugary-call.rs
new file mode 100644
index 00000000000..c77ee9914ef
--- /dev/null
+++ b/src/test/run-pass/unboxed-closures-direct-sugary-call.rs
@@ -0,0 +1,17 @@
+// Copyright 2014 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.
+
+#![feature(unboxed_closures, overloaded_calls)]
+
+fn main() {
+    let mut unboxed = |&mut:| {};
+    unboxed();
+}
+