@@ -18,6 +18,7 @@ use crate::{
18
18
FullyCompiledProgram ,
19
19
} ;
20
20
use move_command_line_common:: parser:: { parse_u16, parse_u256, parse_u32} ;
21
+ use move_core_types:: account_address:: AccountAddress ;
21
22
use move_ir_types:: location:: * ;
22
23
use move_symbol_pool:: Symbol ;
23
24
use std:: {
@@ -36,6 +37,7 @@ type ModuleMembers = BTreeMap<Name, ModuleMemberKind>;
36
37
struct Context < ' env , ' map > {
37
38
module_members : UniqueMap < ModuleIdent , ModuleMembers > ,
38
39
named_address_mapping : Option < & ' map NamedAddressMap > ,
40
+ address_conflicts : BTreeSet < Symbol > ,
39
41
address : Option < Address > ,
40
42
aliases : AliasMap ,
41
43
is_source_definition : bool ,
@@ -52,6 +54,7 @@ impl<'env, 'map> Context<'env, 'map> {
52
54
fn new (
53
55
compilation_env : & ' env mut CompilationEnv ,
54
56
module_members : UniqueMap < ModuleIdent , ModuleMembers > ,
57
+ address_conflicts : BTreeSet < Symbol > ,
55
58
) -> Self {
56
59
let mut all_filter_alls = WarningFilters :: new_for_dependency ( ) ;
57
60
for allow in compilation_env. filter_attributes ( ) {
@@ -63,6 +66,7 @@ impl<'env, 'map> Context<'env, 'map> {
63
66
module_members,
64
67
env : compilation_env,
65
68
named_address_mapping : None ,
69
+ address_conflicts,
66
70
address : None ,
67
71
aliases : AliasMap :: new ( ) ,
68
72
is_source_definition : false ,
@@ -122,6 +126,40 @@ impl<'env, 'map> Context<'env, 'map> {
122
126
}
123
127
}
124
128
129
+ /// We mark named addresses as having a conflict if there is not a bidirectional mapping between
130
+ /// the name and its value
131
+ fn compute_address_conflicts (
132
+ pre_compiled_lib : Option < & FullyCompiledProgram > ,
133
+ prog : & P :: Program ,
134
+ ) -> BTreeSet < Symbol > {
135
+ let mut name_to_addr: BTreeMap < Symbol , BTreeSet < AccountAddress > > = BTreeMap :: new ( ) ;
136
+ let mut addr_to_name: BTreeMap < AccountAddress , BTreeSet < Symbol > > = BTreeMap :: new ( ) ;
137
+ let all_addrs = prog. named_address_maps . all ( ) . iter ( ) . chain (
138
+ pre_compiled_lib
139
+ . iter ( )
140
+ . flat_map ( |pre| pre. parser . named_address_maps . all ( ) ) ,
141
+ ) ;
142
+ for map in all_addrs {
143
+ for ( n, addr) in map {
144
+ let n = * n;
145
+ let addr = addr. into_inner ( ) ;
146
+ name_to_addr. entry ( n) . or_default ( ) . insert ( addr) ;
147
+ addr_to_name. entry ( addr) . or_default ( ) . insert ( n) ;
148
+ }
149
+ }
150
+ let name_to_addr_conflicts = name_to_addr
151
+ . into_iter ( )
152
+ . filter ( |( _, addrs) | addrs. len ( ) > 1 )
153
+ . map ( |( n, _) | n) ;
154
+ let addr_to_name_conflicts = addr_to_name
155
+ . into_iter ( )
156
+ . filter ( |( _, addrs) | addrs. len ( ) > 1 )
157
+ . flat_map ( |( _, ns) | ns. into_iter ( ) ) ;
158
+ name_to_addr_conflicts
159
+ . chain ( addr_to_name_conflicts)
160
+ . collect ( )
161
+ }
162
+
125
163
//**************************************************************************************************
126
164
// Entry
127
165
//**************************************************************************************************
@@ -131,17 +169,20 @@ pub fn program(
131
169
pre_compiled_lib : Option < & FullyCompiledProgram > ,
132
170
prog : P :: Program ,
133
171
) -> E :: Program {
172
+ let address_conflicts = compute_address_conflicts ( pre_compiled_lib, & prog) ;
134
173
let module_members = {
135
174
let mut members = UniqueMap :: new ( ) ;
136
175
all_module_members (
137
176
compilation_env,
177
+ & address_conflicts,
138
178
& prog. named_address_maps ,
139
179
& mut members,
140
180
true ,
141
181
& prog. source_definitions ,
142
182
) ;
143
183
all_module_members (
144
184
compilation_env,
185
+ & address_conflicts,
145
186
& prog. named_address_maps ,
146
187
& mut members,
147
188
true ,
@@ -151,6 +192,7 @@ pub fn program(
151
192
assert ! ( pre_compiled. parser. lib_definitions. is_empty( ) ) ;
152
193
all_module_members (
153
194
compilation_env,
195
+ & address_conflicts,
154
196
& pre_compiled. parser . named_address_maps ,
155
197
& mut members,
156
198
false ,
@@ -160,7 +202,7 @@ pub fn program(
160
202
members
161
203
} ;
162
204
163
- let mut context = Context :: new ( compilation_env, module_members) ;
205
+ let mut context = Context :: new ( compilation_env, module_members, address_conflicts ) ;
164
206
165
207
let mut source_module_map = UniqueMap :: new ( ) ;
166
208
let mut lib_module_map = UniqueMap :: new ( ) ;
@@ -296,6 +338,7 @@ fn address_without_value_error(suggest_declaration: bool, loc: Loc, n: &Name) ->
296
338
fn address ( context : & mut Context , suggest_declaration : bool , ln : P :: LeadingNameAccess ) -> Address {
297
339
address_ (
298
340
context. env ,
341
+ & context. address_conflicts ,
299
342
context. named_address_mapping . as_ref ( ) . unwrap ( ) ,
300
343
suggest_declaration,
301
344
ln,
@@ -304,6 +347,7 @@ fn address(context: &mut Context, suggest_declaration: bool, ln: P::LeadingNameA
304
347
305
348
fn address_ (
306
349
compilation_env : & mut CompilationEnv ,
350
+ address_conflicts : & BTreeSet < Symbol > ,
307
351
named_address_mapping : & NamedAddressMap ,
308
352
suggest_declaration : bool ,
309
353
ln : P :: LeadingNameAccess ,
@@ -312,11 +356,15 @@ fn address_(
312
356
let sp ! ( loc, ln_) = ln;
313
357
match ln_ {
314
358
P :: LeadingNameAccess_ :: AnonymousAddress ( bytes) => {
315
- debug_assert ! ( name_res. is_ok( ) ) ; //
316
- Address :: Numerical ( None , sp ( loc, bytes) )
359
+ debug_assert ! ( name_res. is_ok( ) ) ;
360
+ Address :: anonymous ( loc, bytes)
317
361
}
318
362
P :: LeadingNameAccess_ :: Name ( n) => match named_address_mapping. get ( & n. value ) . copied ( ) {
319
- Some ( addr) => Address :: Numerical ( Some ( n) , sp ( loc, addr) ) ,
363
+ Some ( addr) => Address :: Numerical {
364
+ name : Some ( n) ,
365
+ value : sp ( loc, addr) ,
366
+ name_conflict : address_conflicts. contains ( & n. value ) ,
367
+ } ,
320
368
None => {
321
369
if name_res. is_ok ( ) {
322
370
compilation_env. add_diag ( address_without_value_error (
@@ -416,7 +464,7 @@ fn set_sender_address(
416
464
context
417
465
. env
418
466
. add_diag ( diag ! ( Declarations :: InvalidModule , ( loc, msg) ) ) ;
419
- Address :: Numerical ( None , sp ( loc, NumericalAddress :: DEFAULT_ERROR_ADDRESS ) )
467
+ Address :: anonymous ( loc, NumericalAddress :: DEFAULT_ERROR_ADDRESS )
420
468
}
421
469
} )
422
470
}
@@ -801,7 +849,7 @@ fn attribute_value(
801
849
match avalue_ {
802
850
PV :: Value ( v) => EV :: Value ( value ( context, v) ?) ,
803
851
PV :: ModuleAccess ( sp ! ( ident_loc, PN :: Two ( sp!( aloc, LN :: AnonymousAddress ( a) ) , n) ) ) => {
804
- let addr = Address :: Numerical ( None , sp ( aloc, a) ) ;
852
+ let addr = Address :: anonymous ( aloc, a) ;
805
853
let mident = sp ( ident_loc, ModuleIdent_ :: new ( addr, ModuleName ( n) ) ) ;
806
854
if context. module_members . get ( & mident) . is_none ( ) {
807
855
context. env . add_diag ( diag ! (
@@ -940,6 +988,7 @@ fn warning_filter(
940
988
941
989
fn all_module_members < ' a > (
942
990
compilation_env : & mut CompilationEnv ,
991
+ address_conflicts : & BTreeSet < Symbol > ,
943
992
named_addr_maps : & NamedAddressMaps ,
944
993
members : & mut UniqueMap < ModuleIdent , ModuleMembers > ,
945
994
always_add : bool ,
@@ -958,21 +1007,21 @@ fn all_module_members<'a>(
958
1007
Some ( a) => {
959
1008
address_ (
960
1009
compilation_env,
1010
+ address_conflicts,
961
1011
named_addr_map,
962
1012
/* suggest_declaration */ true ,
963
1013
* a,
964
1014
)
965
1015
}
966
1016
// Error will be handled when the module is compiled
967
- None => {
968
- Address :: Numerical ( None , sp ( m. loc , NumericalAddress :: DEFAULT_ERROR_ADDRESS ) )
969
- }
1017
+ None => Address :: anonymous ( m. loc , NumericalAddress :: DEFAULT_ERROR_ADDRESS ) ,
970
1018
} ;
971
1019
module_members ( members, always_add, addr, m)
972
1020
}
973
1021
P :: Definition :: Address ( addr_def) => {
974
1022
let addr = address_ (
975
1023
compilation_env,
1024
+ address_conflicts,
976
1025
named_addr_map,
977
1026
/* suggest_declaration */ false ,
978
1027
addr_def. addr ,
0 commit comments