Repository: python/mypy

Issue:
Segmentation fault with custom TypeTraverserVisitor
I'm trying to copy methods from one class into the other, need to add some imports to other class' module. 
https://github.com/django/django/blob/b9cf764be62e77b4777b3a75ec256f6209a57671/django/db/models/manager.py#L101

I'd like to use custom `TypeTraverserVisitor` for that
```
signature_node: FuncDef

def import_symbol_from_source(name: str) -> None:
    if name in source_symbols['__builtins__'].node.names:
        return
    sym = source_symbols[name].copy()
    self.semanal_api.add_imported_symbol(name, sym, context=self.semanal_api.cur_mod_node)

class UnimportedTypesVisitor(TypeTraverserVisitor):
    def visit_instance(self, t: Instance) -> None:
        super().visit_instance(t)
        if isinstance(t.type, FakeInfo):
            return
        type_name = t.type.name
        sym = currently_imported_symbols.get(type_name)
        if sym is None:
            import_symbol_from_source(type_name)

signature_node.type.accept(UnimportedTypesVisitor())
```

Compiled version of mypy segfaults for me, when I'm trying to use code like this. The plain Python version runs just fine. 


Discussion:
Could you try to produce a standalone test case for me to run somehow?

Resolving patch:
diff --git a/mypyc/codegen/emitclass.py b/mypyc/codegen/emitclass.py
--- a/mypyc/codegen/emitclass.py
+++ b/mypyc/codegen/emitclass.py
@@ -129,8 +129,10 @@ def generate_class(cl: ClassIR, module: str, emitter: Emitter) -> None:
     generate_full = not cl.is_trait and not cl.builtin_base
     needs_getseters = not cl.is_generated
 
-    if generate_full:
+    if not cl.builtin_base:
         fields['tp_new'] = new_name
+
+    if generate_full:
         fields['tp_dealloc'] = '(destructor){}_dealloc'.format(name_prefix)
         fields['tp_traverse'] = '(traverseproc){}_traverse'.format(name_prefix)
         fields['tp_clear'] = '(inquiry){}_clear'.format(name_prefix)
@@ -229,6 +231,10 @@ def emit_line() -> None:
         emit_line()
         generate_getseters_table(cl, getseters_name, emitter)
         emit_line()
+
+    if cl.is_trait:
+        generate_new_for_trait(cl, new_name, emitter)
+
     generate_methods_table(cl, methods_name, emitter)
     emit_line()
 
@@ -545,6 +551,27 @@ def generate_new_for_class(cl: ClassIR,
     emitter.emit_line('}')
 
 
+def generate_new_for_trait(cl: ClassIR,
+                           func_name: str,
+                           emitter: Emitter) -> None:
+    emitter.emit_line('static PyObject *')
+    emitter.emit_line(
+        '{}(PyTypeObject *type, PyObject *args, PyObject *kwds)'.format(func_name))
+    emitter.emit_line('{')
+    emitter.emit_line('if (type != {}) {{'.format(emitter.type_struct_name(cl)))
+    emitter.emit_line(
+        'PyErr_SetString(PyExc_TypeError, '
+        '"interpreted classes cannot inherit from compiled traits");'
+    )
+    emitter.emit_line('} else {')
+    emitter.emit_line(
+        'PyErr_SetString(PyExc_TypeError, "traits may not be directly created");'
+    )
+    emitter.emit_line('}')
+    emitter.emit_line('return NULL;')
+    emitter.emit_line('}')
+
+
 def generate_traverse_for_class(cl: ClassIR,
                                 func_name: str,
                                 emitter: Emitter) -> None:


Test patch:
diff --git a/mypyc/test-data/run-traits.test b/mypyc/test-data/run-traits.test
--- a/mypyc/test-data/run-traits.test
+++ b/mypyc/test-data/run-traits.test
@@ -383,3 +383,29 @@ g(c1, c2)
 assert c1.x == 1
 assert c2.x == 2
 [out]
+
+[case testTraitErrorMessages]
+from mypy_extensions import trait
+
+@trait
+class Trait:
+    pass
+
+def create() -> Trait:
+    return Trait()
+
+[file driver.py]
+from native import Trait, create
+from testutil import assertRaises
+
+with assertRaises(TypeError, "traits may not be directly created"):
+    Trait()
+
+with assertRaises(TypeError, "traits may not be directly created"):
+    create()
+
+class Sub(Trait):
+    pass
+
+with assertRaises(TypeError, "interpreted classes cannot inherit from compiled traits"):
+    Sub()