]> git.lizzy.rs Git - rust.git/commitdiff
Fix `tcx.environment` for inherent impls
authorscalexm <alexandre@scalexm.fr>
Fri, 30 Nov 2018 14:06:49 +0000 (15:06 +0100)
committerscalexm <alexandre@scalexm.fr>
Thu, 27 Dec 2018 18:21:16 +0000 (19:21 +0100)
src/librustc_traits/lowering/environment.rs

index abd776fab862fbceda8f52b562d487b806439a5b..962a145814c8b53028c36f2e5e5069431c97abf3 100644 (file)
@@ -216,56 +216,73 @@ fn visit_clause(&mut self, clause: Clause<'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(