diff --git a/CHANGELOG.md b/CHANGELOG.md
index 794318838c7f4e54f5f46baafcc05889f25d0e12..b98949c4008148205ef297980a96aa80c75dd825 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,11 @@
+## Next
+
+* Fixed [#165](https://github.com/manastech/crystal/issues/165): restrictions with generic types didn't work for hierarchy types.
+
 ## 0.3.3 (2014-07-14)
 
 * Allow implicit conversion to C types by defining a `to_unsafe` method. This removed the hardcoded rule for converting a `String` to `UInt8*` and also allows passing an `Array(T)` to an argument expecting `Pointer(T)`.
-* Fixed `.is_a?(Class)` not working (#162)
+* Fixed `.is_a?(Class)` not working ([#162](https://github.com/manastech/crystal/issues/162))
 * Attributes are now associated to AST nodes in the semantic pass, not during parsing. This allows macros to generate attributes that will be attached to subsequent expressions.
 * **(breaking change)** Make ENV#[] raise on missing key, and added ENV#[]?
 * **(breaking change)** Macro defs are now written like `macro def name(args) : ReturnType` instead of `def name(args) : ReturnType`, which was a bit confusing.
diff --git a/spec/compiler/codegen/def_spec.cr b/spec/compiler/codegen/def_spec.cr
index 99692c048f27592ce77c90fc0184e8131c36d4c9..963dab311658b8fa99ce469cc50eb3dacddca94e 100755
--- a/spec/compiler/codegen/def_spec.cr
+++ b/spec/compiler/codegen/def_spec.cr
@@ -463,4 +463,35 @@ describe "Code gen: def" do
       foo(node)
       ").to_i.should eq(1)
   end
+
+  it "dispatches on hierarchy type implementing generic module (related to bug #165)" do
+    run("
+      module Moo(T)
+        def moo
+          1
+        end
+      end
+
+      abstract class Foo
+      end
+
+      class Bar < Foo
+        include Moo(Int32)
+      end
+
+      class Baz < Foo
+      end
+
+      def method(x : Moo(Int32))
+        x.moo
+      end
+
+      def method(x : Baz)
+        2
+      end
+
+      foo = Bar.new || Baz.new
+      method(foo)
+      ").to_i.should eq(1)
+  end
 end
diff --git a/spec/compiler/type_inference/def_spec.cr b/spec/compiler/type_inference/def_spec.cr
index 0ae4e7310bbcef92640c7b2aa48d9d71c7639f8f..2bb02df297e55eea3be56003927d1c0038ba12d2 100755
--- a/spec/compiler/type_inference/def_spec.cr
+++ b/spec/compiler/type_inference/def_spec.cr
@@ -303,4 +303,18 @@ describe "Type inference: def" do
       b.foo
       ) { int32 }
   end
+
+  it "fixes bug #165" do
+    assert_error %(
+      abstract class Node
+      end
+
+      def foo(nodes : Pointer(Node))
+        foo nodes.value
+      end
+
+      a = Pointer(Node).new(0_u64)
+      foo a
+      ), "no overload matches"
+  end
 end
diff --git a/src/compiler/crystal/type_inference/restrictions.cr b/src/compiler/crystal/type_inference/restrictions.cr
index 4a526da8c7e02f4f573cafa3d13a8c94684b4efe..ac8cee09c07438b87a9d3ba29786e44c0ae38d87 100644
--- a/src/compiler/crystal/type_inference/restrictions.cr
+++ b/src/compiler/crystal/type_inference/restrictions.cr
@@ -381,6 +381,15 @@ module Crystal
         nil
       end
     end
+
+    def restrict(other : Generic, owner, type_lookup, free_vars)
+      types = [] of Type
+      base_type.subclasses.each do |subclass|
+        restricted = subclass.hierarchy_type.restrict(other, owner, type_lookup, free_vars)
+        types << restricted if restricted
+      end
+      program.type_merge_union_of types
+    end
   end
 
   class AliasType