From 5a99d798577a1e5a3e5434bad4b68835b708f6c0 Mon Sep 17 00:00:00 2001
From: Michael Rosenberg <42micro@gmail.com>
Date: Wed, 13 Jul 2016 01:36:09 -0400
Subject: [PATCH] Fixed issue where importing a trait method directly and then
 calling the method causes a compiler panic

---
 src/librustc_resolve/resolve_imports.rs      | 28 +++++++++++++-------
 src/test/compile-fail/import-trait-method.rs | 17 ++++++++++++
 2 files changed, 35 insertions(+), 10 deletions(-)
 create mode 100644 src/test/compile-fail/import-trait-method.rs

diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 16a59fbb800..681d9ec735b 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -400,26 +400,30 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
         }
     }
 
-    /// Resolves an `ImportResolvingError` into the correct enum discriminant
-    /// and passes that on to `resolve_error`.
-    fn import_resolving_error(&self, e: ImportResolvingError<'b>) {
-        // If it's a single failed import then create a "fake" import
-        // resolution for it so that later resolve stages won't complain.
-        if let SingleImport { target, .. } = e.import_directive.subclass {
+    // Define a "dummy" resolution containing a Def::Err as a placeholder for a
+    // failed resolution
+    fn import_dummy_binding(&self, source_module: Module<'b>, directive: &'b ImportDirective<'b>) {
+        if let SingleImport { target, .. } = directive.subclass {
             let dummy_binding = self.resolver.arenas.alloc_name_binding(NameBinding {
                 kind: NameBindingKind::Def(Def::Err),
                 span: DUMMY_SP,
                 vis: ty::Visibility::Public,
             });
-            let dummy_binding = e.import_directive.import(dummy_binding, None);
+            let dummy_binding = directive.import(dummy_binding, None);
 
-            let _ = e.source_module.try_define_child(target, ValueNS, dummy_binding.clone());
-            let _ = e.source_module.try_define_child(target, TypeNS, dummy_binding);
+            let _ = source_module.try_define_child(target, ValueNS, dummy_binding.clone());
+            let _ = source_module.try_define_child(target, TypeNS, dummy_binding);
         }
+    }
 
+    /// Resolves an `ImportResolvingError` into the correct enum discriminant
+    /// and passes that on to `resolve_error`.
+    fn import_resolving_error(&self, e: ImportResolvingError<'b>) {
+        // If the error is a single failed import then create a "fake" import
+        // resolution for it so that later resolve stages won't complain.
+        self.import_dummy_binding(e.source_module, e.import_directive);
         let path = import_path_to_string(&e.import_directive.module_path,
                                          &e.import_directive.subclass);
-
         resolve_error(self.resolver,
                       e.span,
                       ResolutionError::UnresolvedImport(Some((&path, &e.help))));
@@ -500,6 +504,10 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
                 if !binding.is_importable() {
                     let msg = format!("`{}` is not directly importable", target);
                     span_err!(self.resolver.session, directive.span, E0253, "{}", &msg);
+                    // Do not import this illegal binding. Import a dummy binding and pretend
+                    // everything is fine
+                    self.import_dummy_binding(module_, directive);
+                    return Success(());
                 }
 
                 let privacy_error = if !self.resolver.is_accessible(binding.vis) {
diff --git a/src/test/compile-fail/import-trait-method.rs b/src/test/compile-fail/import-trait-method.rs
new file mode 100644
index 00000000000..75081b10d86
--- /dev/null
+++ b/src/test/compile-fail/import-trait-method.rs
@@ -0,0 +1,17 @@
+// Copyright 2016 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.
+
+trait Foo {
+    fn foo();
+}
+
+use Foo::foo; //~ ERROR not directly importable
+
+fn main() { foo(); }