Skip to content

Commit d0339c7

Browse files
committed
Fix help for duplicated names: extern crate (...) as (...)
On the case of duplicated names caused by an `extern crate` statement with a rename, don't include the inline suggestion, instead using a span label with only the text to avoid incorrect rust code output.
1 parent 7f6417e commit d0339c7

File tree

9 files changed

+74
-8
lines changed

9 files changed

+74
-8
lines changed

src/librustc_resolve/build_reduced_graph.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ impl<'a> Resolver<'a> {
250250
}
251251
}
252252

253-
ItemKind::ExternCrate(_) => {
253+
ItemKind::ExternCrate(as_name) => {
254254
self.crate_loader.process_item(item, &self.definitions);
255255

256256
// n.b. we don't need to look at the path option here, because cstore already did
@@ -265,7 +265,7 @@ impl<'a> Resolver<'a> {
265265
id: item.id,
266266
parent,
267267
imported_module: Cell::new(Some(module)),
268-
subclass: ImportDirectiveSubclass::ExternCrate,
268+
subclass: ImportDirectiveSubclass::ExternCrate(as_name),
269269
span: item.span,
270270
module_path: Vec::new(),
271271
vis: Cell::new(vis),

src/librustc_resolve/check_unused.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
120120
_ if directive.used.get() ||
121121
directive.vis.get() == ty::Visibility::Public ||
122122
directive.span.source_equal(&DUMMY_SP) => {}
123-
ImportDirectiveSubclass::ExternCrate => {
123+
ImportDirectiveSubclass::ExternCrate(_) => {
124124
resolver.maybe_unused_extern_crates.push((directive.id, directive.span));
125125
}
126126
ImportDirectiveSubclass::MacroUse => {

src/librustc_resolve/lib.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -1118,7 +1118,7 @@ impl<'a> NameBinding<'a> {
11181118
match self.kind {
11191119
NameBindingKind::Import {
11201120
directive: &ImportDirective {
1121-
subclass: ImportDirectiveSubclass::ExternCrate, ..
1121+
subclass: ImportDirectiveSubclass::ExternCrate(_), ..
11221122
}, ..
11231123
} => true,
11241124
_ => false,
@@ -1132,6 +1132,15 @@ impl<'a> NameBinding<'a> {
11321132
}
11331133
}
11341134

1135+
fn is_renamed_extern_crate(&self) -> bool {
1136+
if let NameBindingKind::Import { directive, ..} = self.kind {
1137+
if let ImportDirectiveSubclass::ExternCrate(Some(_)) = directive.subclass {
1138+
return true;
1139+
}
1140+
}
1141+
false
1142+
}
1143+
11351144
fn is_glob_import(&self) -> bool {
11361145
match self.kind {
11371146
NameBindingKind::Import { directive, .. } => directive.is_glob(),
@@ -3700,7 +3709,8 @@ impl<'a> Resolver<'a> {
37003709
let cm = self.session.codemap();
37013710
let rename_msg = "You can use `as` to change the binding name of the import";
37023711

3703-
if let Ok(snippet) = cm.span_to_snippet(binding.span) {
3712+
if let (Ok(snippet), false) = (cm.span_to_snippet(binding.span),
3713+
binding.is_renamed_extern_crate()) {
37043714
err.span_suggestion(binding.span,
37053715
rename_msg,
37063716
format!("{} as Other{}", snippet, name));

src/librustc_resolve/resolve_imports.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc::hir::def_id::DefId;
2323
use rustc::hir::def::*;
2424
use rustc::util::nodemap::{FxHashMap, FxHashSet};
2525

26-
use syntax::ast::{Ident, SpannedIdent, NodeId};
26+
use syntax::ast::{Ident, Name, SpannedIdent, NodeId};
2727
use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
2828
use syntax::ext::hygiene::Mark;
2929
use syntax::parse::token;
@@ -48,7 +48,7 @@ pub enum ImportDirectiveSubclass<'a> {
4848
max_vis: Cell<ty::Visibility>, // The visibility of the greatest reexport.
4949
// n.b. `max_vis` is only used in `finalize_import` to check for reexport errors.
5050
},
51-
ExternCrate,
51+
ExternCrate(Option<Name>),
5252
MacroUse,
5353
}
5454

@@ -923,7 +923,7 @@ fn import_directive_subclass_to_string(subclass: &ImportDirectiveSubclass) -> St
923923
match *subclass {
924924
SingleImport { source, .. } => source.to_string(),
925925
GlobImport { .. } => "*".to_string(),
926-
ExternCrate => "<extern crate>".to_string(),
926+
ExternCrate(_) => "<extern crate>".to_string(),
927927
MacroUse => "#[macro_use]".to_string(),
928928
}
929929
}

src/test/compile-fail/E0259.rs

+1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ extern crate libc as alloc;
1818
//~^ ERROR E0259
1919
//~| NOTE `alloc` reimported here
2020
//~| NOTE `alloc` must be defined only once in the type namespace of this module
21+
//~| NOTE You can use `as` to change the binding name of the import
2122

2223
fn main() {}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub fn foo() {}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub fn bar() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// aux-build:m1.rs
12+
// aux-build:m2.rs
13+
14+
15+
extern crate m1;
16+
extern crate m2 as m1;
17+
18+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0259]: the name `m1` is defined multiple times
2+
--> $DIR/extern-crate-rename.rs:16:1
3+
|
4+
15 | extern crate m1;
5+
| ---------------- previous import of the extern crate `m1` here
6+
16 | extern crate m2 as m1;
7+
| ^^^^^^^^^^^^^^^^^^^^^^
8+
| |
9+
| `m1` reimported here
10+
| You can use `as` to change the binding name of the import
11+
|
12+
= note: `m1` must be defined only once in the type namespace of this module
13+
14+
error: aborting due to previous error
15+

0 commit comments

Comments
 (0)