@@ -20,6 +20,7 @@ tag scope {
20
20
scope_crate( @ast. crate ) ;
21
21
scope_item ( @ast. item ) ;
22
22
scope_native_item ( @ast. native_item ) ;
23
+ scope_external_mod ( ast. def_id , vec[ ast. ident ] ) ;
23
24
scope_loop ( @ast. decl ) ; // there's only 1 decl per loop.
24
25
scope_block ( ast. block ) ;
25
26
scope_arm ( ast. arm ) ;
@@ -37,6 +38,8 @@ tag def_wrap {
37
38
def_wrap_import ( @ast. view_item ) ;
38
39
def_wrap_mod ( @ast. item ) ;
39
40
def_wrap_native_mod ( @ast. item ) ;
41
+ def_wrap_external_mod ( ast. def_id ) ;
42
+ def_wrap_external_native_mod ( ast. def_id ) ;
40
43
def_wrap_other ( def) ;
41
44
def_wrap_expr_field ( uint, def) ;
42
45
def_wrap_resolving;
@@ -79,6 +82,12 @@ fn unwrap_def(def_wrap d) -> def {
79
82
}
80
83
}
81
84
}
85
+ case ( def_wrap_external_mod ( ?mod_id) ) {
86
+ ret ast. def_mod ( mod_id) ;
87
+ }
88
+ case ( def_wrap_external_native_mod ( ?mod_id) ) {
89
+ ret ast. def_native_mod ( mod_id) ;
90
+ }
82
91
case ( def_wrap_other ( ?d) ) {
83
92
ret d;
84
93
}
@@ -100,6 +109,30 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] {
100
109
}
101
110
}
102
111
112
+ fn lookup_external_def ( session . session sess, int cnum , vec[ ident] idents )
113
+ -> option. t[ def_wrap ] {
114
+ alt ( creader. lookup_def ( sess, cnum, idents) ) {
115
+ case ( none[ ast. def ] ) {
116
+ ret none[ def_wrap] ;
117
+ }
118
+ case ( some[ ast. def ] ( ?def) ) {
119
+ auto dw;
120
+ alt ( def) {
121
+ case ( ast. def_mod ( ?mod_id) ) {
122
+ dw = def_wrap_external_mod ( mod_id) ;
123
+ }
124
+ case ( ast. def_native_mod ( ?mod_id) ) {
125
+ dw = def_wrap_external_native_mod ( mod_id) ;
126
+ }
127
+ case ( _) {
128
+ dw = def_wrap_other ( def) ;
129
+ }
130
+ }
131
+ ret some[ def_wrap] ( dw) ;
132
+ }
133
+ }
134
+ }
135
+
103
136
// Follow the path of an import and return what it ultimately points to.
104
137
105
138
// If used after imports are resolved, import_id is none.
@@ -136,12 +169,43 @@ fn find_final_def(&env e, import_map index,
136
169
}
137
170
}
138
171
172
+ // TODO: Refactor with above.
173
+ fn found_external_mod ( & env e, & import_map index, & span sp,
174
+ vec[ ident] idents , ast. def_id mod_id )
175
+ -> def_wrap {
176
+ auto len = _vec. len [ ident] ( idents) ;
177
+ auto rest_idents = _vec. slice [ ident] ( idents, 1 u, len) ;
178
+ auto empty_e = rec ( scopes = nil[ scope] , sess = e. sess ) ;
179
+ auto tmp_e = update_env_for_external_mod ( empty_e, mod_id, idents) ;
180
+ auto next_i = rest_idents. ( 0 ) ;
181
+ auto next_ = lookup_name_wrapped ( tmp_e, next_i) ;
182
+ alt ( next_) {
183
+ case ( none[ tup ( @env, def_wrap) ] ) {
184
+ e. sess . span_err ( sp, "unresolved name: " + next_i) ;
185
+ fail;
186
+ }
187
+ case ( some[ tup ( @env, def_wrap) ] ( ?next) ) {
188
+ auto combined_e = update_env_for_external_mod ( e,
189
+ mod_id,
190
+ idents) ;
191
+ ret found_something ( combined_e, index, sp,
192
+ rest_idents, next. _1 ) ;
193
+ }
194
+ }
195
+ }
196
+
139
197
fn found_crate ( & env e, & import_map index, & span sp,
140
198
vec[ ident] idents , int cnum ) -> def_wrap {
141
199
auto len = _vec. len [ ident] ( idents) ;
142
200
auto rest_idents = _vec. slice [ ident] ( idents, 1 u, len) ;
143
- auto def = creader. lookup_def ( e. sess , sp, cnum, rest_idents) ;
144
- ret def_wrap_other ( def) ;
201
+ alt ( lookup_external_def ( e. sess , cnum, rest_idents) ) {
202
+ case ( none[ def_wrap] ) {
203
+ e. sess . span_err ( sp, #fmt ( "unbound name '%s'" ,
204
+ _str. connect ( idents, "." ) ) ) ;
205
+ fail;
206
+ }
207
+ case ( some[ def_wrap] ( ?dw) ) { ret dw; }
208
+ }
145
209
}
146
210
147
211
alt ( d) {
@@ -168,6 +232,12 @@ fn find_final_def(&env e, import_map index,
168
232
case ( def_wrap_native_mod ( ?i) ) {
169
233
ret found_mod ( e, index, sp, idents, i) ;
170
234
}
235
+ case ( def_wrap_external_mod ( ?mod_id) ) {
236
+ ret found_external_mod ( e, index, sp, idents, mod_id) ;
237
+ }
238
+ case ( def_wrap_external_native_mod ( ?mod_id) ) {
239
+ ret found_external_mod ( e, index, sp, idents, mod_id) ;
240
+ }
171
241
case ( def_wrap_use ( ?vi) ) {
172
242
alt ( vi. node ) {
173
243
case ( ast. view_item_use ( _, _, _, ?cnum_opt) ) {
@@ -390,7 +460,8 @@ fn lookup_name_wrapped(&env e, ast.ident i) -> option.t[tup(@env, def_wrap)] {
390
460
}
391
461
}
392
462
393
- fn in_scope ( ast . ident i, & scope s) -> option. t[ def_wrap ] {
463
+ fn in_scope ( & session . session sess, ast . ident i, & scope s)
464
+ -> option. t[ def_wrap ] {
394
465
alt ( s) {
395
466
396
467
case ( scope_crate ( ?c) ) {
@@ -450,6 +521,10 @@ fn lookup_name_wrapped(&env e, ast.ident i) -> option.t[tup(@env, def_wrap)] {
450
521
}
451
522
}
452
523
524
+ case ( scope_external_mod ( ?mod_id, ?path) ) {
525
+ ret lookup_external_def ( sess, mod_id. _0 , path) ;
526
+ }
527
+
453
528
case ( scope_loop ( ?d) ) {
454
529
alt ( d. node ) {
455
530
case ( ast. decl_local ( ?local) ) {
@@ -483,7 +558,7 @@ fn lookup_name_wrapped(&env e, ast.ident i) -> option.t[tup(@env, def_wrap)] {
483
558
ret none[ tup ( @env, def_wrap) ] ;
484
559
}
485
560
case ( cons[ scope] ( ?hd, ?tl) ) {
486
- auto x = in_scope ( i, hd) ;
561
+ auto x = in_scope ( e . sess , i, hd) ;
487
562
alt ( x) {
488
563
case ( some[ def_wrap] ( ?x) ) {
489
564
ret some ( tup ( @e, x) ) ;
@@ -613,6 +688,15 @@ fn update_env_for_native_item(&env e, @ast.native_item i) -> env {
613
688
ret rec ( scopes = cons[ scope] ( scope_native_item ( i) , @e. scopes ) with e) ;
614
689
}
615
690
691
+ // Not actually called by fold, but here since this is analogous to
692
+ // update_env_for_item() above and is called by find_final_def().
693
+ fn update_env_for_external_mod ( & env e, ast. def_id mod_id ,
694
+ vec[ ast. ident] idents ) -> env {
695
+ ret rec ( scopes = cons[ scope] ( scope_external_mod ( mod_id, idents) ,
696
+ @e. scopes )
697
+ with e) ;
698
+ }
699
+
616
700
fn update_env_for_block ( & env e, & ast . block b) -> env {
617
701
ret rec ( scopes = cons[ scope] ( scope_block ( b) , @e. scopes ) with e) ;
618
702
}
0 commit comments