about summary refs log tree commit diff
diff options
context:
space:
mode:
authorscalexm <alexandre@scalexm.fr>2018-11-30 15:06:49 +0100
committerscalexm <alexandre@scalexm.fr>2018-12-27 19:21:16 +0100
commit3790f08a42afd07835f9eec72db1d56235d32eed (patch)
tree5f9aca92707aa0b5c70d792cbf20e8b5627ad2d6
parent8e2bdaacac450695d62a34365803845378bc9121 (diff)
Fix `tcx.environment` for inherent impls
-rw-r--r--src/librustc_traits/lowering/environment.rs79
1 files changed, 48 insertions, 31 deletions
diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs
index abd776fab86..962a145814c 100644
--- a/src/librustc_traits/lowering/environment.rs
+++ b/src/librustc_traits/lowering/environment.rs
@@ -216,56 +216,73 @@ crate fn environment<'a, 'tcx>(
     let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
     let node = tcx.hir().get(node_id);
 
-    let mut is_fn = false;
-    let mut is_impl = false;
-    match node {
+    enum NodeKind {
+        TraitImpl,
+        InherentImpl,
+        Fn,
+        Other,
+    };
+
+    let node_kind = match node {
         Node::TraitItem(item) => match item.node {
-            TraitItemKind::Method(..) => is_fn = true,
-            _ => (),
+            TraitItemKind::Method(..) => NodeKind::Fn,
+            _ => NodeKind::Other,
         }
 
         Node::ImplItem(item) => match item.node {
-            ImplItemKind::Method(..) => is_fn = true,
-            _ => (),
+            ImplItemKind::Method(..) => NodeKind::Fn,
+            _ => NodeKind::Other,
         }
 
         Node::Item(item) => match item.node {
-            ItemKind::Impl(..) => is_impl = true,
-            ItemKind::Fn(..) => is_fn = true,
-            _ => (),
+            ItemKind::Impl(.., Some(..), _, _) => NodeKind::TraitImpl,
+            ItemKind::Impl(.., None, _, _) => NodeKind::InherentImpl,
+            ItemKind::Fn(..) => NodeKind::Fn,
+            _ => NodeKind::Other,
         }
 
         Node::ForeignItem(item) => match item.node {
-            ForeignItemKind::Fn(..) => is_fn = true,
-            _ => (),
+            ForeignItemKind::Fn(..) => NodeKind::Fn,
+            _ => NodeKind::Other,
         }
 
         // FIXME: closures?
-        _ => (),
-    }
+        _ => NodeKind::Other,
+    };
 
     let mut input_tys = FxHashSet::default();
 
-    // In an impl, we assume that the header trait ref and all its constituents
-    // are well-formed.
-    if is_impl {
-        let trait_ref = tcx.impl_trait_ref(def_id)
-            .expect("not an impl");
+    match node_kind {
+        // In a trait impl, we assume that the header trait ref and all its
+        // constituents are well-formed.
+        NodeKind::TraitImpl => {
+            let trait_ref = tcx.impl_trait_ref(def_id)
+                .expect("not an impl");
 
-        input_tys.extend(
-            trait_ref.input_types().flat_map(|ty| ty.walk())
-        );
-    }
+            input_tys.extend(
+                trait_ref.input_types().flat_map(|ty| ty.walk())
+            );
+        }
 
-    // In an fn, we assume that the arguments and all their constituents are
-    // well-formed.
-    if is_fn {
-        let fn_sig = tcx.fn_sig(def_id);
-        let fn_sig = tcx.liberate_late_bound_regions(def_id, &fn_sig);
+        // In an inherent impl, we assume that the receiver type and all its
+        // constituents are well-formed.
+        NodeKind::InherentImpl => {
+            let self_ty = tcx.type_of(def_id);
+            input_tys.extend(self_ty.walk());
+        }
 
-        input_tys.extend(
-            fn_sig.inputs().iter().flat_map(|ty| ty.walk())
-        );
+        // In an fn, we assume that the arguments and all their constituents are
+        // well-formed.
+        NodeKind::Fn => {
+            let fn_sig = tcx.fn_sig(def_id);
+            let fn_sig = tcx.liberate_late_bound_regions(def_id, &fn_sig);
+
+            input_tys.extend(
+                fn_sig.inputs().iter().flat_map(|ty| ty.walk())
+            );
+        }
+
+        NodeKind::Other => (),
     }
 
     let clauses = clauses.chain(