angelikatyborska

angelikatyborska

Why does Code.compile_string report deprecation warnings only sometimes?

I’m having trouble understanding why function deprecation warnings don’t always show up when I compile code that uses deprecated functions.

Let me explain with an example: HashDict.new/0 is a deprecated function. Let’s say I have a file called deprecated_test.ex. The file contains a module and a function definition that uses the deprecated function:

# deprecated_test.ex
defmodule Foo do
  def foo, do: HashDict.new()
end

If I compile the file with elixirc, I get a nice deprecation warning:

angelika in ~/Documents
$ elixirc deprecated_test.ex
warning: HashDict.new/0 is deprecated. Use maps and the Map module instead
  deprecated_test.ex:2: Foo.foo/0

However, if I start iex, load the same file and compile it with Code.compile_string/1, I don’t get the warning:

iex(2)> code = File.read!("./deprecated_test.ex")
"defmodule Foo do\n  def foo, do: HashDict.new()\nend\n"

iex(3)> Code.compile_string(code)
[
  {Foo,
   <<70, 79, 82, 49, 0, 0, 4, 208, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0,
     153, 0, 0, 0, 16, 10, 69, 108, 105, 120, 105, 114, 46, 70, 111, 111, 8, 95,
     95, 105, 110, 102, 111, 95, 95, 10, 97, 116, ...>>}
]

I thought this means that Code.compile_string/1 won’t give me deprecation warnings at all, but that’s not true.

I get a deprecation warning about HashDict.new/0 if I try different code snippets:

iex(4)> Code.compile_string("fn -> HashDict.new() end")
warning: HashDict.new/0 is deprecated. Use maps and the Map module instead
  nofile:1

[]

or

iex(15)> Code.compile_string("ref = &HashDict.new/0")
warning: HashDict.new/0 is deprecated. Use maps and the Map module instead
  nofile:1

warning: variable "ref" is unused (if the variable is not meant to be used, prefix it with an underscore)
  nofile:1

[]

Why is this happening? Can I somehow ensure that I will always get exactly the same deprecation warnings when compiling code with Code.compile_string/1 and/or Code.compile_quoted/1 as I would get with elixirc?

Marked As Solved

josevalim

josevalim

Creator of Elixir

Both :elixir_compiler and Module.ParallelChecker are private, so please don’t use them. :slight_smile: Please open up an issue and we will make sure to also check for deprecations from compile_string. :slight_smile:

Also Liked

moogle19

moogle19

It seems that compile_file/2 call the private function verify_loaded/1 in Code which verifies some things (e.g. deprecations) (see code.ex#L1503).
compile_string/2 doens’t (see code.ex#L1466).

Not sure why only the compile_file/2 checks this. Maybe performance reasons?

angelikatyborska

angelikatyborska

Thanks a lot! Based on your hints, I was able to get the deprecation checks working fully.

The only purpose of my code is to get all the compilation warnings. Here’s what I had before:

warnings =
  capture_io(:stderr, fn ->
    Code.compile_quoted(code_ast, Path.basename(code_path))
    |> Enum.each(fn {module, _binary} ->
      :code.delete(module)
      :code.purge(module)
    end)
  end)

And here’s what I have now:

warnings =
  capture_io(:stderr, fn ->
    :elixir_compiler.quoted(code_ast, code_path, fn _, _ -> :ok end)
    |> Enum.each(fn {module, map, binary} ->
      Module.ParallelChecker.verify([{map, binary}], [])
      :code.delete(module)
      :code.purge(module)
    end)
  end)

I’m just not sure if it’s a great idea to use a private module (Module.ParallelChecker) like this.

Where Next?

Popular in Questions Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lists...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
nobody
How to bind a phoenix app to a specific ip address? could not find anything about that, nowhere, unfortunately, but for me this is quite...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New

Other popular topics Top

siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36128 110
New
Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 126479 1222
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

We're in Beta

About us Mission Statement