Awlexus

Awlexus

I’m getting the following warning when compiling my project and I’m not sure how to resolve it, because from what I see there is a proper pattern match

Warning
    warning: a struct for Plug.Upload is expected on struct update:

        %Plug.Upload{image | filename: random_filename(name)}

    but got type:

        dynamic()

    where "image" was given the type:

        # type: dynamic()
        # from: my_file.ex:95:79
        %{"image" => %Plug.Upload{filename: name} = image} = params

    when defining the variable "image", you must also pattern match on "%Plug.Upload{}".

    hint: given pattern matching is enough to catch typing errors, you may optionally convert the struct update into a map update. For example, instead of:

        user = some_function()
        %User{user | name: "John Doe"}

    it is enough to write:

        %User{} = user = some_function()
        %{user | name: "John Doe"}

    typing violation found at:
    │
 96 │     image = %Plug.Upload{image | filename: random_filename(name)}
    │             ~
    │
    └─ my_file.ex:96:13: MyModule.put_random_filename/1

Code
  defp put_random_filename(%{"image" => %Plug.Upload{filename: name} = image} = params) do
    image = %Plug.Upload{image | filename: random_filename(name)}
    %{params | "image" => image}
  end

  defp put_random_filename(params), do: params
Elixir -v

Erlang/OTP 28 [erts-16.1.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit]

Elixir 1.19.2 (compiled with Erlang/OTP 28)

Different variations that trigger the same warning

No match against file name
  defp put_random_filename(%{"image" => %Plug.Upload{} = image} = params) do
    image = %Plug.Upload{image | filename: random_filename(image.filename)}
    %{params | "image" => image}
  end
Flipping the assignment
  defp put_random_filename(%{"image" => image = %Plug.Upload{filename: name}} = params) do
    image = %Plug.Upload{image | filename: random_filename(name)}
    %{params | "image" => image}
  end

Showing Posts 1 to 10

a-maze-d

a-maze-d

image = %Plug.Upload{image | filename: random_filename(name)}

What about rewiting this to:

image = %{image | filename: random_filename(name)}
Awlexus

Awlexus OP

Thanks, that does fix the warning. I would rather call this a workaround than a solution though :thinking:

garrison

garrison

Surely this is a bug? The struct is clearly typed. Maybe someone with more knowledge will reply, but I would say file an issue.

Does this infer properly?

def foo(%{"image" => image}) do
  %Plug.Upload{} = image
  %Plug.Upload{image | filename: "foo"}
end
Awlexus

Awlexus OP

I’ve tried these 2 variations. Both trigger the warning

  defp put_random_filename(%{"image" => image} = params) do
    %Plug.Upload{filename: name} = image
    image = %Plug.Upload{image | filename: random_filename(name)}
    %{params | "image" => image}
  end

  defp put_random_filename(%{"image" => image} = params) do
    %Plug.Upload{} = image
    image = %Plug.Upload{image | filename: random_filename(image.filename)}
    %{params | "image" => image}
  end
garrison

garrison

Maybe I’m missing something but that doesn’t seem right to me. There was a lot of back-and-forth on what to do with the “struct update” syntax and I’m not sure what the final decision was there, but I feel like those examples should work, right?

a-maze-d

a-maze-d

It’s not a bug. The compoler does accept it (except if you turn warnings to errors)

There is no benefited value to specify the struct in the update. Therefore the recommendation to drop it.

I think we just need to get used to the new style

tfwright

tfwright

Is there an official statement on that somewhere? I haven’t tried out 1.19 yet but this doesn’t match my understanding of either of the possibilities that were being considered. If it is the struct update syntax itself being deprecated shouldn’t the warning specifically say that rather than missing pattern match? Or what could be the point of warning about it if it’s not deprecated?

a-maze-d

a-maze-d

The release note for 1.9 states:

[Kernel] The struct update syntax, such as %URI{uri | path: "/foo/bar"}, now requires the given variable (or expression) to explicitly pattern match on the struct before it can be updated. This is because, thanks to the type system, pattern matching on structs can find more errors, more reliably, and we want to promote its usage. Once pattern matching is added, you may optionally convert the struct update syntax into the map update syntax %{uri | path: "/foo/bar"} with no less of typing guarantees

tfwright

tfwright

explicitly pattern match on the struct before it can be updated.

then it seems like the code in Warning about missing pattern match, despite pattern matching - #5 by Awlexus should not generate a warning? Isn’t the first line of each function an “explicit pattern match”?

garrison

garrison

The syntax was going to be deprecated but that decision changed. In this commit the changelog was updated to suggest that the syntax is allowed but you must pattern match on the struct first. Which is what all of the examples in this thread are doing.

Personally I stopped using the struct update syntax in anticipation of this change several months ago, but that doesn’t mean the compiler should be spitting out nonsensical warnings! I think this is just a bug.

Where Next? Top

Trending in Questions Top

Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
Onor.io
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
jaybe78
Hello, I’m developing a online persistent chat system (what’s app) like using elixir/dynamodb/aws for a mobile app(flutter). The diffic...
New
Trolleger
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New
matt-savvy
Anyone here using Honeybadger? My Honeybadger account is being overwhelmed with noise from some bots. Seeing a lot of Bandit.HTTPError...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New

Other Trending Topics Top

garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New
webofbits
Aludel - LLM Evaluation Workbench Aludel is an embeddable Phoenix LiveView dashboard for evaluating and comparing LLM prompts across mult...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews