@@ -8,7 +8,7 @@ import front::attr;
8
8
import metadata:: { csearch, cstore} ;
9
9
import driver:: session:: session;
10
10
import util:: common:: * ;
11
- import std:: map:: { new_int_hash, new_str_hash} ;
11
+ import std:: map:: { new_int_hash, new_str_hash, mk_hashmap } ;
12
12
import syntax:: codemap:: span;
13
13
import syntax:: visit;
14
14
import visit:: vt;
@@ -117,16 +117,18 @@ type indexed_mod = {
117
117
118
118
type def_map = hashmap < node_id , def > ;
119
119
type ext_map = hashmap < def_id , [ ident ] > ;
120
- type exp_map = hashmap < str , @mutable [ def ] > ;
121
120
type impl_map = hashmap < node_id , iscopes > ;
122
121
type impl_cache = hashmap < def_id , option < @[ @_impl ] > > ;
123
122
123
+ type exp = { reexp : bool , id : def_id } ;
124
+ type exp_map = hashmap < node_id , [ exp ] > ;
125
+
124
126
type env =
125
127
{ cstore : cstore:: cstore ,
126
128
def_map : def_map ,
127
129
ast_map : ast_map:: map ,
128
130
imports : hashmap < ast:: node_id , import_state > ,
129
- exp_map : exp_map ,
131
+ mutable exp_map: exp_map ,
130
132
mod_map : hashmap < ast:: node_id , @indexed_mod > ,
131
133
block_map : hashmap < ast:: node_id , [ glob_imp_def ] > ,
132
134
ext_map : ext_map ,
@@ -188,7 +190,7 @@ fn create_env(sess: session, amap: ast_map::map) -> @env {
188
190
def_map: new_int_hash ( ) ,
189
191
ast_map: amap,
190
192
imports: new_int_hash ( ) ,
191
- exp_map: new_str_hash ( ) ,
193
+ mutable exp_map: new_int_hash ( ) ,
192
194
mod_map: new_int_hash ( ) ,
193
195
block_map: new_int_hash ( ) ,
194
196
ext_map: new_def_hash ( ) ,
@@ -2005,63 +2007,59 @@ fn check_exports(e: @env) {
2005
2007
2006
2008
2007
2009
2008
- fn lookup_glob_any ( e : @env , info : @indexed_mod , sp : span , path : str ,
2009
- ident : ident ) -> bool {
2010
- let lookup =
2011
- bind lookup_glob_in_mod ( * e, info, sp, ident, _, inside) ;
2012
- let ( m, v, t) = ( lookup ( ns_module) ,
2013
- lookup ( ns_val ( value_or_enum) ) ,
2014
- lookup ( ns_type) ) ;
2015
- let full_path = path + ident;
2016
- maybe_add_reexport ( e, full_path, m) ;
2017
- maybe_add_reexport ( e, full_path, v) ;
2018
- maybe_add_reexport ( e, full_path, t) ;
2010
+ fn lookup_glob_any ( e : @env , info : @indexed_mod , sp : span ,
2011
+ ident : ident , export_id : node_id ) -> bool {
2012
+ let m = lookup_glob_in_mod ( * e, info, sp, ident, ns_module, inside) ;
2013
+ let v = lookup_glob_in_mod ( * e, info, sp, ident, ns_val ( value_or_enum) ,
2014
+ inside) ;
2015
+ let t = lookup_glob_in_mod ( * e, info, sp, ident, ns_type, inside) ;
2016
+ maybe_add_reexport ( e, export_id, m) ;
2017
+ maybe_add_reexport ( e, export_id, v) ;
2018
+ maybe_add_reexport ( e, export_id, t) ;
2019
2019
is_some ( m) || is_some ( v) || is_some ( t)
2020
2020
}
2021
2021
2022
- fn maybe_add_reexport ( e : @env , path : str , def : option < def > ) {
2023
- alt def {
2024
- some( def) {
2025
- alt e. exp_map . find ( path) {
2026
- some ( v) {
2027
- // If there are multiple reexports of the same def
2028
- // using the same path, then we only need one copy
2029
- if !vec:: contains ( * v, def) {
2030
- * v += [ def] ;
2031
- }
2032
- }
2033
- none { e. exp_map . insert ( path, @mutable [ def] ) ; }
2034
- }
2035
- }
2036
- _ { }
2022
+
2023
+ fn maybe_add_reexport ( e : @env , export_id : node_id , def : option < def > ) {
2024
+ option:: may ( def) { |def|
2025
+ add_export ( e, export_id, def_id_of_def ( def) , true ) ;
2037
2026
}
2038
2027
}
2028
+ fn add_export ( e : @env , export_id : node_id , target_id : def_id ,
2029
+ reexp : bool ) {
2030
+ let found = alt e. exp_map . find ( export_id) {
2031
+ some ( f) { f } none { [ ] }
2032
+ } ;
2033
+ e. exp_map . insert ( export_id, found + [ { reexp: reexp, id: target_id} ] ) ;
2034
+ }
2039
2035
2040
2036
fn check_export ( e : @env , ident : str , _mod : @indexed_mod ,
2041
- vi : @view_item ) {
2037
+ export_id : node_id , vi : @view_item ) {
2042
2038
let found_something = false ;
2043
- let full_path = _mod. path + ident;
2044
2039
if _mod. index . contains_key ( ident) {
2045
2040
found_something = true ;
2046
2041
let xs = _mod. index . get ( ident) ;
2047
2042
list:: iter ( xs) { |x|
2048
2043
alt x {
2049
2044
mie_import_ident( id, _) {
2050
- alt e. imports . get ( id) {
2045
+ alt check e. imports . get ( id) {
2051
2046
resolved ( v, t, m, _, rid, _) {
2052
- maybe_add_reexport ( e, full_path , v) ;
2053
- maybe_add_reexport ( e, full_path , t) ;
2054
- maybe_add_reexport ( e, full_path , m) ;
2047
+ maybe_add_reexport ( e, export_id , v) ;
2048
+ maybe_add_reexport ( e, export_id , t) ;
2049
+ maybe_add_reexport ( e, export_id , m) ;
2055
2050
}
2056
- _ { }
2057
2051
}
2058
2052
}
2053
+ mie_item ( @{ id, _} ) | mie_native_item ( @{ id, _} ) |
2054
+ mie_enum_variant ( _, _, id, _) {
2055
+ add_export ( e, export_id, local_def ( id) , false ) ;
2056
+ }
2059
2057
_ { }
2060
2058
}
2061
2059
}
2062
2060
}
2063
- found_something |= lookup_glob_any ( e, _mod, vi. span ,
2064
- _mod . path , ident ) ;
2061
+ found_something |= lookup_glob_any ( e, _mod, vi. span , ident ,
2062
+ export_id ) ;
2065
2063
if !found_something {
2066
2064
e. sess . span_warn ( vi. span ,
2067
2065
#fmt ( "exported item %s is not defined" , ident) ) ;
@@ -2071,64 +2069,54 @@ fn check_exports(e: @env) {
2071
2069
fn check_enum_ok ( e : @env , sp : span , id : ident , _mod : @indexed_mod )
2072
2070
-> node_id {
2073
2071
alt _mod. index . find ( id) {
2074
- none { e. sess . span_fatal ( sp, #fmt ( "undefined id %s \
2075
- in an export", id) ) ; }
2076
- some ( ms) {
2077
- let maybe_id = list:: find ( ms) { |m|
2078
- alt m {
2079
- mie_item( an_item) {
2080
- alt an_item. node {
2081
- item_enum ( _, _) { /* OK */ some ( an_item. id ) }
2082
- _ { none }
2083
- }
2084
- }
2085
- _ { none }
2086
- }
2087
- } ;
2088
- alt maybe_id {
2089
- some( an_id) { ret an_id; }
2090
- _ { e. sess . span_fatal ( sp, #fmt ( "%s does not refer \
2091
- to an enumeration", id) ) ; }
2092
- }
2093
- }
2094
- }
2072
+ none {
2073
+ e. sess . span_fatal ( sp, #fmt ( "undefined id %s in an export" , id) ) ;
2074
+ }
2075
+ some ( ms) {
2076
+ let maybe_id = list:: find ( ms) { |m|
2077
+ alt m {
2078
+ mie_item( @{ node : item_enum ( _, _) , id, _} ) { some ( id) }
2079
+ _ { none }
2080
+ }
2081
+ } ;
2082
+ alt maybe_id {
2083
+ some( an_id) { an_id }
2084
+ _ { e. sess . span_fatal ( sp, #fmt ( "%s does not refer \
2085
+ to an enumeration", id) ) ; }
2086
+ }
2087
+ }
2088
+ }
2095
2089
}
2096
2090
2097
- fn check_export_enum_list ( e : @env , _mod : @indexed_mod ,
2091
+ fn check_export_enum_list ( e : @env , export_id : node_id , _mod : @indexed_mod ,
2098
2092
span : codemap:: span , id : ast:: ident ,
2099
2093
ids : [ ast:: path_list_ident ] ) {
2100
- if vec:: len ( ids) == 0 u {
2101
- let _ = check_enum_ok ( e, span, id, _mod) ;
2102
- } else {
2103
- let parent_id = check_enum_ok ( e, span, id, _mod) ;
2104
- for variant_id in ids {
2105
- alt _mod. index . find ( variant_id. node . name ) {
2106
- some ( ms) {
2107
- list:: iter ( ms) { |m|
2108
- alt m {
2109
- mie_enum_variant( _, _, actual_parent_id, _) {
2110
- if actual_parent_id != parent_id {
2111
- let msg = #fmt ( "variant %s \
2112
- doesn't belong to enum %s",
2113
- variant_id. node . name ,
2114
- id) ;
2115
- e. sess . span_err ( span, msg) ;
2116
- }
2117
- }
2118
- _ {
2119
- e. sess . span_err ( span,
2120
- #fmt ( "%s is not a variant" ,
2121
- variant_id. node . name ) ) ;
2122
- }
2094
+ let parent_id = check_enum_ok ( e, span, id, _mod) ;
2095
+ add_export ( e, export_id, local_def ( parent_id) , false ) ;
2096
+ for variant_id in ids {
2097
+ let found = false ;
2098
+ alt _mod. index . find ( variant_id. node . name ) {
2099
+ some ( ms) {
2100
+ list:: iter ( ms) { |m|
2101
+ alt m {
2102
+ mie_enum_variant( _, _, actual_parent_id, _) {
2103
+ found = true ;
2104
+ if actual_parent_id != parent_id {
2105
+ e. sess . span_err (
2106
+ span, #fmt ( "variant %s doesn't belong to \
2107
+ enum %s",
2108
+ variant_id. node . name , id) ) ;
2123
2109
}
2110
+ }
2111
+ _ { }
2124
2112
}
2125
- }
2126
- _ {
2127
- e. sess . span_err ( span,
2128
- #fmt ( "%s is not a variant" ,
2129
- variant_id. node . name ) ) ;
2130
- }
2131
2113
}
2114
+ }
2115
+ _ { }
2116
+ }
2117
+ if !found {
2118
+ e. sess . span_err ( span, #fmt ( "%s is not a variant" ,
2119
+ variant_id. node . name ) ) ;
2132
2120
}
2133
2121
}
2134
2122
}
@@ -2141,17 +2129,17 @@ fn check_exports(e: @env) {
2141
2129
for vi in m. view_items {
2142
2130
iter_export_paths ( * vi) { |vp|
2143
2131
alt vp. node {
2144
- ast:: view_path_simple ( ident, _, _ ) {
2145
- check_export ( e, ident, _mod, vi) ;
2132
+ ast:: view_path_simple ( ident, _, id ) {
2133
+ check_export ( e, ident, _mod, id , vi) ;
2146
2134
}
2147
- ast:: view_path_list ( path, ids, _ ) {
2135
+ ast:: view_path_list ( path, ids, node_id ) {
2148
2136
let id = if vec:: len ( * path) == 1 u {
2149
2137
path[ 0 ]
2150
2138
} else {
2151
- e. sess . span_fatal ( vp. span ,
2152
- #fmt ( "bad export name-list" ) )
2139
+ e. sess . span_fatal ( vp. span , "bad export name-list" )
2153
2140
} ;
2154
- check_export_enum_list ( e, _mod, vp. span , id, ids) ;
2141
+ check_export_enum_list ( e, node_id, _mod, vp. span , id,
2142
+ ids) ;
2155
2143
}
2156
2144
ast:: view_path_glob ( _, node_id) {
2157
2145
glob_is_re_exported. insert ( node_id, ( ) ) ;
@@ -2162,18 +2150,14 @@ fn check_exports(e: @env) {
2162
2150
// Now follow the export-glob links and fill in the
2163
2151
// globbed_exports and exp_map lists.
2164
2152
for glob in _mod. glob_imports {
2165
- alt check glob. path . node {
2166
- ast:: view_path_glob ( path, node_id) {
2167
- if ! glob_is_re_exported. contains_key ( node_id) {
2168
- cont;
2169
- }
2170
- }
2171
- }
2153
+ let id = alt check glob. path . node {
2154
+ ast:: view_path_glob ( _, node_id) { node_id }
2155
+ } ;
2156
+ if ! glob_is_re_exported. contains_key ( id) { cont; }
2172
2157
iter_mod ( * e, glob. def ,
2173
2158
glob. path . span , outside) { |ident, def|
2174
- let full_path = _mod. path + ident;
2175
2159
_mod. globbed_exports += [ ident] ;
2176
- maybe_add_reexport ( e, full_path , some ( def) ) ;
2160
+ maybe_add_reexport ( e, id , some ( def) ) ;
2177
2161
}
2178
2162
}
2179
2163
}
0 commit comments