11-module (elixir_module ).
22-export ([file /1 , data_tables /1 , is_open /1 , mode /1 , delete_definition_attributes /6 ,
3- compile /4 , expand_callback /6 , format_error /1 , compiler_modules /0 ,
3+ compile /5 , expand_callback /6 , format_error /1 , compiler_modules /0 ,
44 write_cache /3 , read_cache /2 , next_counter /1 ]).
55-include (" elixir.hrl" ).
66-define (counter_attr , {elixir , counter }).
@@ -64,7 +64,7 @@ next_counter(Module) ->
6464
6565% % Compilation hook
6666
67- compile (Module , Block , Vars , Env ) when is_atom (Module ) ->
67+ compile (Module , Block , Vars , Prune , Env ) when is_atom (Module ) ->
6868 #{line := Line , function := Function , versioned_vars := OldVerVars } = Env ,
6969
7070 {VerVars , _ } =
@@ -82,16 +82,16 @@ compile(Module, Block, Vars, Env) when is_atom(Module) ->
8282 #{lexical_tracker := nil } ->
8383 elixir_lexical :run (
8484 MaybeLexEnv ,
85- fun (LexEnv ) -> compile (Line , Module , Block , Vars , LexEnv ) end ,
85+ fun (LexEnv ) -> compile (Line , Module , Block , Vars , Prune , LexEnv ) end ,
8686 fun (_LexEnv ) -> ok end
8787 );
8888 _ ->
89- compile (Line , Module , Block , Vars , MaybeLexEnv )
89+ compile (Line , Module , Block , Vars , Prune , MaybeLexEnv )
9090 end ;
91- compile (Module , _Block , _Vars , #{line := Line , file := File }) ->
91+ compile (Module , _Block , _Vars , _Prune , #{line := Line , file := File }) ->
9292 elixir_errors :form_error ([{line , Line }], File , ? MODULE , {invalid_module , Module }).
9393
94- compile (Line , Module , Block , Vars , E ) ->
94+ compile (Line , Module , Block , Vars , Prune , E ) ->
9595 File = ? key (E , file ),
9696 check_module_availability (Line , File , Module ),
9797 ModuleAsCharlist = validate_module_name (Line , File , Module ),
@@ -102,7 +102,7 @@ compile(Line, Module, Block, Vars, E) ->
102102
103103 try
104104 put_compiler_modules ([Module | CompilerModules ]),
105- {Result , NE } = eval_form (Line , Module , DataBag , Block , Vars , E ),
105+ {Result , ModuleE , CallbackE } = eval_form (Line , Module , DataBag , Block , Vars , Prune , E ),
106106 CheckerInfo = checker_info (),
107107
108108 {Binary , PersistedAttributes , Autoload } =
@@ -133,7 +133,7 @@ compile(Line, Module, Block, Vars, E) ->
133133 CompileOpts = validate_compile_opts (RawCompileOpts , AllDefinitions , Unreachable , File , Line ),
134134
135135 AfterVerify = bag_lookup_element (DataBag , {accumulate , after_verify }, 2 ),
136- [elixir_env :trace ({remote_function , [], VerifyMod , VerifyFun , 1 }, E ) ||
136+ [elixir_env :trace ({remote_function , [], VerifyMod , VerifyFun , 1 }, CallbackE ) ||
137137 {VerifyMod , VerifyFun } <- AfterVerify ],
138138
139139 ModuleMap = #{
@@ -158,8 +158,8 @@ compile(Line, Module, Block, Vars, E) ->
158158 end ),
159159
160160 Autoload andalso code :load_binary (Module , beam_location (ModuleAsCharlist ), Binary ),
161- eval_callbacks (Line , DataBag , after_compile , [NE , Binary ], NE ),
162- elixir_env :trace ({on_module , Binary , none }, E ),
161+ eval_callbacks (Line , DataBag , after_compile , [CallbackE , Binary ], CallbackE ),
162+ elixir_env :trace ({on_module , Binary , none }, ModuleE ),
163163 warn_unused_attributes (File , DataSet , DataBag , PersistedAttributes ),
164164 make_module_available (Module , Binary ),
165165 (CheckerInfo == undefined ) andalso
@@ -375,13 +375,27 @@ build(Line, File, Module) ->
375375
376376% % Handles module and callback evaluations.
377377
378- eval_form (Line , Module , DataBag , Block , Vars , E ) ->
379- {Value , EE } = elixir_compiler :compile (Block , Vars , E ),
378+ eval_form (Line , Module , DataBag , Block , Vars , Prune , E ) ->
379+ {Value , ExS , EE } = elixir_compiler :compile (Block , Vars , E ),
380380 elixir_overridable :store_not_overridden (Module ),
381381 EV = (elixir_env :reset_vars (EE ))#{line := Line },
382382 EC = eval_callbacks (Line , DataBag , before_compile , [EV ], EV ),
383383 elixir_overridable :store_not_overridden (Module ),
384- {Value , EC }.
384+ {Value , maybe_prune_versioned_vars (Prune , Vars , ExS , E ), EC }.
385+
386+ maybe_prune_versioned_vars (false , _Vars , _Exs , E ) ->
387+ E ;
388+ maybe_prune_versioned_vars (true , Vars , ExS , E ) ->
389+ PruneBefore = length (Vars ),
390+ # elixir_ex {vars = {ExVars , _ }, unused = {Unused , _ }} = ExS ,
391+
392+ VersionedVars =
393+ maps :filter (fun
394+ (Pair , Version ) when Version < PruneBefore , not is_map_key ({Pair , Version }, Unused ) -> false ;
395+ (_ , _ ) -> true
396+ end , ExVars ),
397+
398+ E #{versioned_vars := VersionedVars }.
385399
386400eval_callbacks (Line , DataBag , Name , Args , E ) ->
387401 Callbacks = bag_lookup_element (DataBag , {accumulate , Name }, 2 ),
0 commit comments