Skip to content

Commit de35288

Browse files
committed
rustc: Fail when there are multiple matches for 'use'
1 parent 0255bf3 commit de35288

File tree

3 files changed

+49
-9
lines changed

3 files changed

+49
-9
lines changed

src/librustsyntax/attr.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import diagnostic::span_handler;
77

88
export attr_meta;
99
export attr_metas;
10+
export find_linkage_attrs;
1011
export find_linkage_metas;
1112
export inline_attr;
1213
export find_inline_attr;
@@ -36,14 +37,22 @@ export native_abi;
3637
// From a list of crate attributes get only the meta_items that impact crate
3738
// linkage
3839
fn find_linkage_metas(attrs: [ast::attribute]) -> [@ast::meta_item] {
39-
let mut metas: [@ast::meta_item] = [];
40+
find_linkage_attrs(attrs).flat_map {|attr|
41+
alt check attr.node.value.node {
42+
ast::meta_list(_, items) { items }
43+
}
44+
}
45+
}
46+
47+
fn find_linkage_attrs(attrs: [ast::attribute]) -> [ast::attribute] {
48+
let mut found = [];
4049
for attr: ast::attribute in find_attrs_by_name(attrs, "link") {
4150
alt attr.node.value.node {
42-
ast::meta_list(_, items) { metas += items; }
51+
ast::meta_list(_, _) { found += [attr] }
4352
_ { #debug("ignoring link attribute that has incorrect type"); }
4453
}
4554
}
46-
ret metas;
55+
ret found;
4756
}
4857

4958
enum inline_attr {

src/rustc/metadata/creader.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ fn default_native_lib_naming(sess: session::session, static: bool) ->
138138
}
139139
}
140140

141-
fn find_library_crate(sess: session::session,
141+
fn find_library_crate(sess: session::session, span: span,
142142
metas: [@ast::meta_item])
143143
-> option<{ident: str, data: @[u8]}> {
144144

@@ -163,15 +163,16 @@ fn find_library_crate(sess: session::session,
163163

164164
let nn = default_native_lib_naming(sess, sess.opts.static);
165165
let x =
166-
find_library_crate_aux(sess, nn, crate_name,
166+
find_library_crate_aux(sess, span, nn, crate_name,
167167
metas, sess.filesearch);
168168
if x != none || sess.opts.static { ret x; }
169169
let nn2 = default_native_lib_naming(sess, true);
170-
ret find_library_crate_aux(sess, nn2, crate_name, metas,
170+
ret find_library_crate_aux(sess, span, nn2, crate_name, metas,
171171
sess.filesearch);
172172
}
173173

174174
fn find_library_crate_aux(sess: session::session,
175+
span: span,
175176
nn: {prefix: str, suffix: str},
176177
crate_name: str,
177178
metas: [@ast::meta_item],
@@ -180,7 +181,8 @@ fn find_library_crate_aux(sess: session::session,
180181
let prefix: str = nn.prefix + crate_name + "-";
181182
let suffix: str = nn.suffix;
182183

183-
ret filesearch::search(filesearch, { |path|
184+
let mut matches = [];
185+
filesearch::search(filesearch, { |path|
184186
#debug("inspecting file %s", path);
185187
let f: str = path::basename(path);
186188
if !(str::starts_with(f, prefix) && str::ends_with(f, suffix)) {
@@ -196,7 +198,8 @@ fn find_library_crate_aux(sess: session::session,
196198
option::none
197199
} else {
198200
#debug("found %s with matching metadata", path);
199-
option::some({ident: path, data: cvec})
201+
matches += [{ident: path, data: cvec}];
202+
option::none
200203
}
201204
}
202205
_ {
@@ -206,6 +209,25 @@ fn find_library_crate_aux(sess: session::session,
206209
}
207210
}
208211
});
212+
213+
if matches.is_empty() {
214+
none
215+
} else if matches.len() == 1u {
216+
some(matches[0])
217+
} else {
218+
sess.span_err(
219+
span, #fmt("multiple matching crates for `%s`", crate_name));
220+
sess.note("candidates:");
221+
for matches.each {|match|
222+
sess.note(#fmt("path: %s", match.ident));
223+
let attrs = decoder::get_crate_attributes(match.data);
224+
for attr::find_linkage_attrs(attrs).each {|attr|
225+
sess.note(#fmt("meta: %s", pprust::attr_to_str(attr)));
226+
}
227+
}
228+
sess.abort_if_errors();
229+
none
230+
}
209231
}
210232

211233
fn get_metadata_section(sess: session::session,
@@ -240,7 +262,7 @@ fn load_library_crate(sess: session::session, ident: ast::ident, span: span,
240262
-> {ident: str, data: @[u8]} {
241263

242264

243-
alt find_library_crate(sess, metas) {
265+
alt find_library_crate(sess, span, metas) {
244266
some(t) { ret t; }
245267
none {
246268
sess.span_fatal(span, #fmt["can't find crate for '%s'", ident]);

src/test/compile-fail/crateresolve.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// aux-build:crateresolve-1.rs
2+
// aux-build:crateresolve-2.rs
3+
// aux-build:crateresolve-3.rs
4+
// error-pattern:multiple matching crates for `crateresolve`
5+
6+
use crateresolve;
7+
8+
fn main() {
9+
}

0 commit comments

Comments
 (0)