Skip to content

Commit 34490d9

Browse files
paulstansifergraydon
authored andcommitted
---
yaml --- r: 2806 b: refs/heads/master c: 40fe44d h: refs/heads/master v: v3
1 parent bdadc17 commit 34490d9

File tree

7 files changed

+178
-56
lines changed

7 files changed

+178
-56
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 22953f52faa3afb24c7024c0373a4895d9c5859b
2+
refs/heads/master: 40fe44d23ea84cc6ce3f4d98506369515a4fcb07

trunk/src/comp/front/ast.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import std::map::hashmap;
21
import std::option;
32
import std::str;
43
import std::vec;

trunk/src/comp/middle/resolve.rs

Lines changed: 69 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,11 @@ tag mod_index_entry {
7676
type mod_index = hashmap[ident,list[mod_index_entry]];
7777

7878
type indexed_mod = rec(option::t[ast::_mod] m,
79-
mod_index index, vec[@i_m] glob_imports);
79+
mod_index index, vec[def] glob_imports);
8080
/* native modules can't contain tags, and we don't store their ASTs because we
8181
only need to look at them to determine exports, which they can't control.*/
8282
// It should be safe to use index to memoize lookups of globbed names.
8383

84-
//FIXME: this only exists because we can't yet write recursive types unless
85-
//the recursion passes through a tag.
86-
tag i_m {
87-
i_m(indexed_mod);
88-
}
89-
9084
type crate_map = hashmap[uint,ast::crate_num];
9185

9286
type def_map = hashmap[uint,def];
@@ -144,7 +138,7 @@ fn map_crate(&@env e, &ast::crate c) {
144138
// Register the top-level mod
145139
e.mod_map.insert(-1, @rec(m=some(c.node.module),
146140
index=index_mod(c.node.module),
147-
glob_imports=vec::empty[@i_m]()));
141+
glob_imports=vec::empty[def]()));
148142
walk::walk_crate(index_names, c);
149143

150144
fn index_vi(@env e, @mutable list[scope] sc, &@ast::view_item i) {
@@ -161,13 +155,13 @@ fn map_crate(&@env e, &ast::crate c) {
161155
case (ast::item_mod(_, ?md, ?defid)) {
162156
e.mod_map.insert(defid._1,
163157
@rec(m=some(md), index=index_mod(md),
164-
glob_imports=vec::empty[@i_m]()));
158+
glob_imports=vec::empty[def]()));
165159
}
166160
case (ast::item_native_mod(_, ?nmd, ?defid)) {
167161
e.mod_map.insert(defid._1,
168162
@rec(m=none[ast::_mod],
169163
index=index_nmod(nmd),
170-
glob_imports=vec::empty[@i_m]()));
164+
glob_imports=vec::empty[def]()));
171165
}
172166
case (_) {}
173167
}
@@ -370,10 +364,8 @@ fn pop_env_for_arm(@mutable list[scope] sc, &ast::arm p) {
370364
*sc = std::list::cdr(*sc);
371365
}
372366

373-
374-
//HERE
375367
fn follow_import(&env e, &list[scope] sc, vec[ident] path, &span sp)
376-
-> @i_m {
368+
-> def {
377369
auto path_len = vec::len(path);
378370
auto dcur = lookup_in_scope_strict(e, sc, sp, path.(0), ns_module);
379371
auto i = 1u;
@@ -385,13 +377,8 @@ fn follow_import(&env e, &list[scope] sc, vec[ident] path, &span sp)
385377
}
386378

387379
alt (dcur) {
388-
case (ast::def_mod(?def_id)) {
389-
//TODO: is this sane?
390-
ret @i_m(*e.mod_map.get(def_id._1));
391-
}
392-
case (ast::def_native_mod(?def_id)) {
393-
ret @i_m(*e.mod_map.get(def_id._1));
394-
}
380+
case (ast::def_mod(?def_id)) { ret dcur; }
381+
case (ast::def_native_mod(?def_id)) { ret dcur; }
395382
case (_) {
396383
e.sess.span_err(sp, str::connect(path, "::")
397384
+ " does not name a module.");
@@ -430,9 +417,12 @@ fn resolve_import(&env e, &@ast::view_item it, &list[scope] sc) {
430417
while (true) {
431418
if (i == n_idents - 1u) {
432419
register(e, defid, it.span, end_id,
433-
lookup_in_mod(e, dcur, end_id, ns_value, outside),
434-
lookup_in_mod(e, dcur, end_id, ns_type, outside),
435-
lookup_in_mod(e, dcur, end_id, ns_module, outside));
420+
lookup_in_mod(e, dcur, it.span, end_id, ns_value,
421+
outside),
422+
lookup_in_mod(e, dcur, it.span, end_id, ns_type,
423+
outside),
424+
lookup_in_mod(e, dcur, it.span, end_id, ns_module,
425+
outside));
436426
break;
437427
} else {
438428
dcur = lookup_in_mod_strict(e, dcur, it.span, ids.(i),
@@ -526,12 +516,12 @@ fn def_is_obj_field(&def d) -> bool {
526516

527517
fn lookup_in_scope(&env e, list[scope] sc, &span sp, &ident id, namespace ns)
528518
-> option::t[def] {
529-
fn in_scope(&env e, &ident id, &scope s, namespace ns)
519+
fn in_scope(&env e, &span sp, &ident id, &scope s, namespace ns)
530520
-> option::t[def] {
531521
alt (s) {
532522
case (scope_crate(?c)) {
533523
auto defid = tup(ast::local_crate, -1);
534-
ret lookup_in_local_mod(e, defid, id, ns, inside);
524+
ret lookup_in_local_mod(e, defid, sp, id, ns, inside);
535525
}
536526
case (scope_item(?it)) {
537527
alt (it.node) {
@@ -547,10 +537,10 @@ fn lookup_in_scope(&env e, list[scope] sc, &span sp, &ident id, namespace ns)
547537
}
548538
}
549539
case (ast::item_mod(_, _, ?defid)) {
550-
ret lookup_in_local_mod(e, defid, id, ns, inside);
540+
ret lookup_in_local_mod(e, defid, sp, id, ns, inside);
551541
}
552542
case (ast::item_native_mod(_, ?m, ?defid)) {
553-
ret lookup_in_local_native_mod(e, defid, id, ns);
543+
ret lookup_in_local_native_mod(e, defid, sp, id, ns);
554544
}
555545
case (ast::item_ty(_, _, ?ty_params, _, _)) {
556546
if (ns == ns_type) {
@@ -599,7 +589,7 @@ fn lookup_in_scope(&env e, list[scope] sc, &span sp, &ident id, namespace ns)
599589
ret none[def];
600590
}
601591
case (cons[scope](?hd, ?tl)) {
602-
auto fnd = in_scope(e, id, hd, ns);
592+
auto fnd = in_scope(e, sp, id, hd, ns);
603593
if (!option::is_none(fnd)) {
604594
auto df = option::get(fnd);
605595
if ((left_fn && def_is_local(df)) ||
@@ -618,6 +608,7 @@ fn lookup_in_scope(&env e, list[scope] sc, &span sp, &ident id, namespace ns)
618608
}
619609
}
620610
e.sess.bug("reached unreachable code in lookup_in_scope"); // sigh
611+
fail;
621612
}
622613

623614
fn lookup_in_ty_params(&ident id, &vec[ast::ty_param] ty_params)
@@ -764,7 +755,7 @@ fn found_def_item(&@ast::item i, namespace ns) -> option::t[def] {
764755

765756
fn lookup_in_mod_strict(&env e, def m, &span sp, &ident id,
766757
namespace ns, dir dr) -> def {
767-
alt (lookup_in_mod(e, m, id, ns, dr)) {
758+
alt (lookup_in_mod(e, m, sp, id, ns, dr)) {
768759
case (none[def]) {
769760
unresolved(e, sp, id, ns_name(ns));
770761
fail;
@@ -775,10 +766,10 @@ fn lookup_in_mod_strict(&env e, def m, &span sp, &ident id,
775766
}
776767
}
777768

778-
fn lookup_in_mod(&env e, def m, &ident id, namespace ns, dir dr)
769+
fn lookup_in_mod(&env e, def m, &span sp, &ident id, namespace ns, dir dr)
779770
-> option::t[def] {
780771
auto defid = ast::def_id_of_def(m);
781-
if (defid._0 != ast::local_crate) { // Not in this crate
772+
if (defid._0 != ast::local_crate) { // examining a mod. in an ext. crate
782773
auto cached = e.ext_cache.find(tup(defid,id,ns));
783774
if (!option::is_none(cached)) { ret cached; }
784775
auto path = [id];
@@ -793,10 +784,10 @@ fn lookup_in_mod(&env e, def m, &ident id, namespace ns, dir dr)
793784
}
794785
alt (m) {
795786
case (ast::def_mod(?defid)) {
796-
ret lookup_in_local_mod(e, defid, id, ns, dr);
787+
ret lookup_in_local_mod(e, defid, sp, id, ns, dr);
797788
}
798789
case (ast::def_native_mod(?defid)) {
799-
ret lookup_in_local_native_mod(e, defid, id, ns);
790+
ret lookup_in_local_native_mod(e, defid, sp, id, ns);
800791
}
801792
}
802793
}
@@ -811,7 +802,7 @@ fn found_view_item(&env e, @ast::view_item vi, namespace ns)
811802
ret lookup_import(e, defid, ns);
812803
}
813804
case (ast::view_item_import_glob(_, ?defid)) {
814-
ret none[def]; //TODO: think about this. Is it correct?
805+
ret none[def]; //will be handled in the fallback glob pass
815806
}
816807
}
817808
}
@@ -834,29 +825,53 @@ fn lookup_import(&env e, def_id defid, namespace ns) -> option::t[def] {
834825
fail;
835826
}
836827

837-
fn lookup_in_local_mod(&env e, def_id defid, &ident id, namespace ns,
838-
dir dr) -> option::t[def] {
828+
fn lookup_in_local_mod(&env e, def_id defid, &span sp, &ident id,
829+
namespace ns, dir dr) -> option::t[def] {
839830
auto info = e.mod_map.get(defid._1);
840-
auto found = info.index.find(id);
841-
if (option::is_none(found) ||
842-
(dr == outside && !ast::is_exported(id, option::get(info.m)))) {
831+
if (dr == outside && !ast::is_exported(id, option::get(info.m))) {
843832
// if we're in a native mod, then dr==inside, so info.m is some _mod
844-
ret none[def];
833+
ret none[def]; // name is not visible
845834
}
846-
auto lst = option::get(found);
847-
while (true) {
848-
alt (lst) {
849-
case (nil[mod_index_entry]) {
850-
ret none[def];
851-
}
852-
case (cons[mod_index_entry](?hd, ?tl)) {
853-
auto found = lookup_in_mie(e, hd, ns);
854-
if (!option::is_none(found)) { ret found; }
855-
lst = *tl;
835+
alt(info.index.find(id)) {
836+
case (none[list[mod_index_entry]]) { }
837+
case (some[list[mod_index_entry]](?lst)) {
838+
while (true) {
839+
alt (lst) {
840+
case (nil[mod_index_entry]) { break; }
841+
case (cons[mod_index_entry](?hd, ?tl)) {
842+
auto found = lookup_in_mie(e, hd, ns);
843+
if (!option::is_none(found)) { ret found; }
844+
lst = *tl;
845+
}
846+
}
856847
}
857848
}
858849
}
859-
e.sess.bug("reached unreachable code in lookup_in_regular_mod"); // sigh
850+
// not local or explicitly imported; try globs:
851+
ret lookup_glob_in_mod(e, info, sp, id, ns, dr);
852+
}
853+
854+
fn lookup_glob_in_mod(&env e, @indexed_mod info, &span sp, &ident id,
855+
namespace ns, dir dr) -> option::t[def] {
856+
fn l_i_m(&env e, &def d, &span sp, &ident id, namespace ns, dir dr)
857+
-> option::t[def] {
858+
ret lookup_in_mod(e, d, sp, id, ns, dr);
859+
}
860+
auto matches = vec::filter_map
861+
(bind l_i_m(e, _, sp, id, ns, dr), info.glob_imports);
862+
if (vec::len(matches) == 0u) {
863+
ret none[def];
864+
} else if (vec::len(matches) == 1u){
865+
ret some[def](matches.(0));
866+
} else {
867+
for (def d in matches) {
868+
e.sess.span_note(sp, "'" + id + "' is defined at " +
869+
util::common::istr(ast::def_id_of_def(d)._1));
870+
}
871+
e.sess.span_err(sp, "'" + id + "' is glob-imported from" +
872+
" multiple different modules.");
873+
fail;
874+
}
860875
}
861876

862877
fn lookup_in_mie(&env e, &mod_index_entry mie, namespace ns)
@@ -899,9 +914,9 @@ fn lookup_in_mie(&env e, &mod_index_entry mie, namespace ns)
899914
ret none[def];
900915
}
901916

902-
fn lookup_in_local_native_mod(&env e, def_id defid, &ident id, namespace ns)
903-
-> option::t[def] {
904-
ret lookup_in_local_mod(e, defid, id, ns, inside);
917+
fn lookup_in_local_native_mod(&env e, def_id defid, &span sp, &ident id,
918+
namespace ns) -> option::t[def] {
919+
ret lookup_in_local_mod(e, defid, sp, id, ns, inside);
905920
}
906921

907922

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
mod module_of_many_things {
2+
export f1, f2, f4;
3+
fn f1() {
4+
log "f1";
5+
}
6+
fn f2() {
7+
log "f2";
8+
}
9+
fn f3() {
10+
log "f3";
11+
}
12+
fn f4() {
13+
log "f4";
14+
}
15+
}
16+
17+
import module_of_many_things::*;
18+
19+
fn main() {
20+
f1();
21+
f2();
22+
f3();
23+
f4();
24+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import module_of_many_things::*;
2+
import dug::too::greedily::and::too::deep::*;
3+
4+
mod module_of_many_things {
5+
export f1;
6+
export f2;
7+
export f4;
8+
fn f1() {
9+
log "f1";
10+
}
11+
fn f2() {
12+
log "f2";
13+
}
14+
fn f3() {
15+
log "f3";
16+
}
17+
fn f4() {
18+
log "f4";
19+
}
20+
}
21+
22+
mod dug {
23+
mod too {
24+
mod greedily {
25+
mod and {
26+
mod too {
27+
mod deep {
28+
fn nameless_fear() {
29+
log "Boo!";
30+
}
31+
fn also_redstone() {
32+
log "Whatever.";
33+
}
34+
fn f1() {}
35+
}
36+
}
37+
}
38+
}
39+
}
40+
}
41+
42+
43+
fn main() {
44+
f1();
45+
f2();
46+
f4();
47+
nameless_fear();
48+
also_redstone();
49+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import a1:b1::word_traveler;
2+
3+
mod a1 { //
4+
mod b1 { //
5+
import a2::b1::*; // <-\
6+
} // |
7+
mod b2 { // |
8+
import a2::b2::*; // <-\ -\ |
9+
} // | | |
10+
} // | | |
11+
// | | |
12+
mod a2 { // | | |
13+
native mod b1 { // | | |
14+
import a1::b2::*; // | <-/ -/
15+
} // |
16+
mod b2 { // |
17+
fn word_traveler() { // |
18+
log "ahoy!"; // -/
19+
} //
20+
} //
21+
} //
22+
23+
24+
fn main() {
25+
word_traveler();
26+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
use std;
3+
import std::vec::*;
4+
5+
fn main() {
6+
auto v = empty[int]();
7+
v += [4,2];
8+
assert(reversed(v) == [2,4]);
9+
}

0 commit comments

Comments
 (0)