elixir-lang / elixir

Elixir is a dynamic, functional language for building scalable and maintainable applications
https://elixir-lang.org/
Apache License 2.0
24.51k stars 3.38k forks source link

Defining @Tributes starting with uppercase crashes compilation #9084

Closed fenollp closed 5 years ago

fenollp commented 5 years ago

Environment

Elixir 1.8.2 (compiled with Erlang/OTP 21)

* Operating system: 

Darwin baobao 18.6.0 Darwin Kernel Version 18.6.0: Thu Apr 25 23:16:27 PDT 2019; root:xnu-4903.261.4~2/RELEASE_X86_64 x86_64 i386 MacBookPro14,1 Darwin


### Current behavior

```elixir
defmodule M do
  @Bla 42

  def bla, do: @Bla
end
== Compilation error in file lib/m.ex ==
** (SyntaxError) lib/m.ex:2: syntax error before: "42"
    (elixir) lib/kernel/parallel_compiler.ex:208: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/6

Expected behaviour

Either

  1. handle module attributes that have the first grapheme of their name capitalized (if they are atoms underneath, quote them?) Both compiler & formatter are affected.
  2. report the error with a more specific message along the lines of Module attributes cannot be capitalized. See @Bla in lib/m.ex:2
josevalim commented 5 years ago

The error is happening in the parser, which means we don't even have a notion of module attributes yet. The issue is that you are trying to write this: @Bar 2, which is the same as +Bar 2, which we can reduce to Bar 2, and it shows that you can't pass arguments to aliases because you can't "call" them.

I understand the error message is quite bad but all error messages coming from the parser are going to be this bad, unfortunately, and generally speaking there isn't much we can do unless we rewrite the whole parser in a tool with better error messages that I am not sure exists at the moment . Sorry. :(

fenollp commented 5 years ago

Wait. How is @Bar 2 the same as +Bar 2?

josevalim commented 5 years ago

@ in Elixir is a unary operator, like +.

fenollp commented 5 years ago

Alright but what makes @ ====== +? As I understand it the reason @ disappears is because it gets turned into a plus sign?

The error is happening in the parser, which means we don't even have a notion of module attributes yet. The issue is that you are trying to write this: @Bar 2, which is the same as +Bar 2, which we can reduce to Bar 2, and it shows that you can't pass arguments to aliases because you can't "call" them.

bar commented 5 years ago

@fenollp I have no idea what you are talking about :)

josevalim commented 5 years ago

Sorry, I didn’t mean to say that @ is literally equal to @, but just that it is also an operator. For example, if the error also manifests for +Bar 2, then it shows it is not a module attribute issue, but a more general one. --

José Valimwww.plataformatec.com.br http://www.plataformatec.com.br/Founder and Director of R&D

fenollp commented 5 years ago

So? Accept atoms around @ / write a special case to your parser? I don't care how it's done, lots of newcomers get bitten by this and it appears terribly unfortunate that the compiler doesn't even catch this.

This cannot be a wontfix.

josevalim commented 5 years ago

@fenollp if you believe the change is straight-forward, then a pull request is absolutely welcome. I personally can't see how to address this and it isn't the first time I try but I may as well be missing something obvious.

josevalim commented 5 years ago

Also, as my previous comments tried to explain, this is not related to @ at all. quote do: @Bar is actually valid AST and it must remain so. But again, I may be missing something obvious.

fertapric commented 5 years ago

@fenollp the documentation for custom module attributes has been clarified a bit https://github.com/elixir-lang/elixir/pull/9109. Hope it helps! 🙂