Repository: hylang/hy

Issue:
Bad (let ) form throws ugly traceback
```
=> (let [x 4] x)        
Traceback (most recent call last):
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 2150, in hy_compile
    result = compiler.compile(tree)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 398, in compile
    ret = self.compile_atom(_type, tree)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 390, in compile_atom
    ret = _compile_table[atom_type](self, atom)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 544, in compile_raw_list
    ret = self._compile_branch(entries)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 429, in _compile_branch
    return _branch(self.compile(expr) for expr in exprs)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 290, in _branch
    results = list(results)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 429, in <genexpr>
    return _branch(self.compile(expr) for expr in exprs)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 398, in compile
    ret = self.compile_atom(_type, tree)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 390, in compile_atom
    ret = _compile_table[atom_type](self, atom)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 1712, in compile_expression
    func = self.compile(fn)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 398, in compile
    ret = self.compile_atom(_type, tree)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 390, in compile_atom
    ret = _compile_table[atom_type](self, atom)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 1686, in compile_expression
    ret = self.compile_atom(fn, expression)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 390, in compile_atom
    ret = _compile_table[atom_type](self, atom)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 333, in checker
    return fn(self, expression)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 1871, in compile_function_def
    body = self._compile_branch(expression)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 429, in _compile_branch
    return _branch(self.compile(expr) for expr in exprs)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 290, in _branch
    results = list(results)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 429, in <genexpr>
    return _branch(self.compile(expr) for expr in exprs)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 410, in compile
    raise HyCompileError(e, sys.exc_info()[2])
HyCompileError: Internal Compiler Bug 

                                       ⤷ TypeError: Can't assign / delete a <class '_ast.Num'> object
Compilation traceback:
File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 398, in compile
    ret = self.compile_atom(_type, tree)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 390, in compile_atom
    ret = _compile_table[atom_type](self, atom)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 1686, in compile_expression
    ret = self.compile_atom(fn, expression)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 390, in compile_atom
    ret = _compile_table[atom_type](self, atom)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 333, in checker
    return fn(self, expression)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 1731, in compile_def_expression
    expression.start_column)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 1742, in _compile_assign
    st_name = self._storeize(ld_name)
  File "/home/at/.local/lib/python2.7/site-packages/hy/compiler.py", line 536, in _storeize
    raise TypeError("Can't assign / delete a %s object" % type(name))
```



Discussion:
Another example: (setv (a b) '(1 2))

Results in a similar stack trace.

With hy master:

```
=> (let [x 4] x)  
  File "<input>", line 1, column 9

  (let [x 4] x)  
          ^^
HyMacroExpansionError: let lexical context element must be a list or symbol
```

The setv one still throws an ugly trace. Will see if I can fix that.


Resolving patch:
diff --git a/hy/compiler.py b/hy/compiler.py
--- a/hy/compiler.py
+++ b/hy/compiler.py
@@ -2004,6 +2004,10 @@ def _compile_assign(self, name, result,
         result = self.compile(result)
         ld_name = self.compile(name)
 
+        if isinstance(ld_name.expr, ast.Call):
+            raise HyTypeError(name,
+                              "Can't assign to a callable: `%s'" % str_name)
+
         if result.temp_variables \
            and isinstance(name, HyString) \
            and '.' not in name:


Test patch:
diff --git a/tests/compilers/test_ast.py b/tests/compilers/test_ast.py
--- a/tests/compilers/test_ast.py
+++ b/tests/compilers/test_ast.py
@@ -519,3 +519,9 @@ def test_attribute_access():
 def test_cons_correct():
     """Ensure cons gets compiled correctly"""
     can_compile("(cons a b)")
+
+
+def test_bad_setv():
+    """Ensure setv handles error cases"""
+    cant_compile("(setv if 1)")
+    cant_compile("(setv (a b) [1 2])")