angelikatyborska

angelikatyborska

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?

Showing Posts 1 to 4

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 OP

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.

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:

angelikatyborska

angelikatyborska OP

That would be great :purple_heart: I opened the issue on GitHub.

— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
apz
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews