Skip to content

Commit 002e382

Browse files
committed
Raise when loading struct info
1 parent 46841a2 commit 002e382

5 files changed

Lines changed: 18 additions & 16 deletions

File tree

lib/elixir/lib/macro.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,7 @@ defmodule Macro do
973973
def struct_info!(module, env) when is_atom(module) do
974974
meta = [line: env.line]
975975

976-
case :elixir_map.maybe_load_struct_info(meta, module, env) do
976+
case :elixir_map.maybe_load_struct_info(meta, module, :hard, env) do
977977
{:ok, info} ->
978978
:elixir_env.trace({:struct_expansion, meta, module, []}, env)
979979
info

lib/elixir/lib/module/types/of.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ defmodule Module.Types.Of do
495495
def struct_info(struct, kind, meta, stack, context) do
496496
case stack.no_warn_undefined do
497497
%Macro.Env{} = env ->
498-
case :elixir_map.maybe_load_struct_info(meta, struct, env) do
498+
case :elixir_map.maybe_load_struct_info(meta, struct, :soft, env) do
499499
{:ok, info} -> {info, context}
500500
{:error, _desc} -> {nil, context}
501501
end

lib/elixir/src/elixir_map.erl

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
%% SPDX-FileCopyrightText: 2012 Plataformatec
44

55
-module(elixir_map).
6-
-export([expand_map/4, expand_struct/5, format_error/1, maybe_load_struct_info/3]).
6+
-export([expand_map/4, expand_struct/5, format_error/1, maybe_load_struct_info/4]).
77
-import(elixir_errors, [function_error/4, file_error/4, file_warn/4]).
88
-include("elixir.hrl").
99

@@ -139,22 +139,19 @@ assert_struct_info_if_not_function(Meta, Name, Assocs, #{function := nil} = E) -
139139
assert_struct_info_if_not_function(_Meta, _Name, _Assocs, _E) ->
140140
ok.
141141

142-
maybe_load_struct_info(Meta, Name, E) ->
143-
maybe_load_struct_info(Meta, Name, soft, E).
144-
145142
maybe_load_struct_info(Meta, Name, Mode, E) ->
146143
try
147-
InContext = in_context(Name, E),
144+
Lookup = in_context(Name, E) orelse is_compiling_struct(Meta, Name, Mode, E),
148145

149-
case (InContext orelse is_compiling_struct(Meta, Name, Mode, E))
150-
andalso lookup_struct_info_from_data_tables(Name) of
146+
case lookup_struct_info_from_data_tables(Name) of
151147
%% If I am accessing myself and there is no attribute,
152148
%% don't invoke the fallback to avoid calling loaded code.
153149
false when ?key(E, module) =:= Name -> nil;
154150
false ->
155-
%% We already attempted to wait for the struct (unless InContext),
156-
%% so we only invoke '__info__' if already loaded or InContext
157-
case InContext orelse erlang:module_loaded(Name) of
151+
%% If we attempted to lookup a definition, we always invoke it, to deal
152+
%% with potential race conditions about the table being deleted at the
153+
%% time we were looking up.
154+
case Lookup orelse erlang:module_loaded(Name) of
158155
true -> Name:'__info__'(struct);
159156
false -> nil
160157
end;

lib/elixir/test/elixir/code_test.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -811,13 +811,13 @@ defmodule CodeTest do
811811
message = "unknown compiler option: :not_a_valid_option"
812812

813813
assert_raise RuntimeError, message, fn ->
814-
Code.put_compiler_option(:not_a_valid_option, :foo)
814+
Code.put_compiler_option(Process.get(:unused, :not_a_valid_option), :ok)
815815
end
816816

817817
message = "compiler option :debug_info should be a boolean, got: :not_a_boolean"
818818

819819
assert_raise RuntimeError, message, fn ->
820-
Code.put_compiler_option(:debug_info, :not_a_boolean)
820+
Code.put_compiler_option(:debug_info, Process.get(:unused, :not_a_boolean))
821821
end
822822
end
823823

lib/elixir/test/elixir/config/provider_test.exs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,13 @@ defmodule Config.ProviderTest do
7777
assert Provider.validate_config_path!("/foo") == :ok
7878
assert Provider.validate_config_path!({:system, "foo", "bar"}) == :ok
7979

80-
assert_raise ArgumentError, fn -> Provider.validate_config_path!({:system, 1, 2}) end
81-
assert_raise ArgumentError, fn -> Provider.validate_config_path!(~c"baz") end
80+
assert_raise ArgumentError, fn ->
81+
Provider.validate_config_path!(Process.get(:unused, {:system, 1, 2}))
82+
end
83+
84+
assert_raise ArgumentError, fn ->
85+
Provider.validate_config_path!(Process.get(:unused, ~c"baz"))
86+
end
8287
end
8388

8489
test "resolve!" do

0 commit comments

Comments
 (0)