Skip to content

Commit 9eacd68

Browse files
committed
manage cases with tabs or other whitespaces
1 parent 4520b30 commit 9eacd68

13 files changed

+204
-29
lines changed

src/librustc_resolve/build_reduced_graph.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
449449
id: item.id,
450450
parent,
451451
imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
452-
subclass: ImportDirectiveSubclass::ExternCrate(orig_name),
452+
subclass: ImportDirectiveSubclass::ExternCrate {
453+
source: orig_name,
454+
target: ident,
455+
},
453456
root_span: item.span,
454457
span: item.span,
455458
module_path: Vec::new(),

src/librustc_resolve/check_unused.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
144144
}
145145
}
146146
}
147-
ImportDirectiveSubclass::ExternCrate(_) => {
147+
ImportDirectiveSubclass::ExternCrate { .. } => {
148148
resolver.maybe_unused_extern_crates.push((directive.id, directive.span));
149149
}
150150
ImportDirectiveSubclass::MacroUse => {

src/librustc_resolve/lib.rs

+34-21
Original file line numberDiff line numberDiff line change
@@ -1234,7 +1234,7 @@ impl<'a> NameBinding<'a> {
12341234
match self.kind {
12351235
NameBindingKind::Import {
12361236
directive: &ImportDirective {
1237-
subclass: ImportDirectiveSubclass::ExternCrate(_), ..
1237+
subclass: ImportDirectiveSubclass::ExternCrate { .. }, ..
12381238
}, ..
12391239
} => true,
12401240
_ => false,
@@ -3794,7 +3794,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
37943794
if let NameBindingKind::Import { directive: d, .. } = binding.kind {
37953795
// Careful: we still want to rewrite paths from
37963796
// renamed extern crates.
3797-
if let ImportDirectiveSubclass::ExternCrate(None) = d.subclass {
3797+
if let ImportDirectiveSubclass::ExternCrate { source: None, .. } = d.subclass {
37983798
return
37993799
}
38003800
}
@@ -4776,7 +4776,15 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
47764776
let cm = self.session.source_map();
47774777
let rename_msg = "you can use `as` to change the binding name of the import";
47784778

4779-
if let Ok(snippet) = cm.span_to_snippet(binding.span) {
4779+
if let (
4780+
Ok(snippet),
4781+
NameBindingKind::Import { directive, ..},
4782+
_x @ 1 ... std::u32::MAX,
4783+
) = (
4784+
cm.span_to_snippet(binding.span),
4785+
binding.kind.clone(),
4786+
binding.span.hi().0,
4787+
) {
47804788
let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() {
47814789
format!("Other{}", name)
47824790
} else {
@@ -4785,24 +4793,29 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
47854793

47864794
err.span_suggestion_with_applicability(
47874795
binding.span,
4788-
rename_msg,
4789-
match (
4790-
snippet.split_whitespace().find(|w| *w == "as"),
4791-
snippet.ends_with(";")
4792-
) {
4793-
(Some(_), false) => format!("{} as {}",
4794-
&snippet[..snippet.find(" as ").unwrap()],
4795-
suggested_name,
4796-
),
4797-
(Some(_), true) => format!("{} as {};",
4798-
&snippet[..snippet.find(" as ").unwrap()],
4799-
suggested_name,
4800-
),
4801-
(None, false) => format!("{} as {}", snippet, suggested_name),
4802-
(None, true) => format!("{} as {};",
4803-
&snippet[..snippet.len() - 1],
4804-
suggested_name
4805-
),
4796+
&rename_msg,
4797+
match (&directive.subclass, snippet.ends_with(";"), snippet.as_ref()) {
4798+
(ImportDirectiveSubclass::SingleImport { .. }, false, "self") =>
4799+
format!("self as {}", suggested_name),
4800+
(ImportDirectiveSubclass::SingleImport { source, .. }, false, _) =>
4801+
format!(
4802+
"{} as {}",
4803+
&snippet[..((source.span.hi().0 - binding.span.lo().0) as usize)],
4804+
suggested_name,
4805+
),
4806+
(ImportDirectiveSubclass::SingleImport { source, .. }, true, _) =>
4807+
format!(
4808+
"{} as {};",
4809+
&snippet[..((source.span.hi().0 - binding.span.lo().0) as usize)],
4810+
suggested_name,
4811+
),
4812+
(ImportDirectiveSubclass::ExternCrate { source, target, .. }, _, _) =>
4813+
format!(
4814+
"extern crate {} as {};",
4815+
source.unwrap_or(target.name),
4816+
suggested_name,
4817+
),
4818+
(_, _, _) => unreachable!(),
48064819
},
48074820
Applicability::MaybeIncorrect,
48084821
);

src/librustc_resolve/resolve_imports.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ pub enum ImportDirectiveSubclass<'a> {
5252
max_vis: Cell<ty::Visibility>, // The visibility of the greatest re-export.
5353
// n.b. `max_vis` is only used in `finalize_import` to check for re-export errors.
5454
},
55-
ExternCrate(Option<Name>),
55+
ExternCrate {
56+
source: Option<Name>,
57+
target: Ident,
58+
},
5659
MacroUse,
5760
}
5861

@@ -1342,7 +1345,7 @@ fn import_directive_subclass_to_string(subclass: &ImportDirectiveSubclass) -> St
13421345
match *subclass {
13431346
SingleImport { source, .. } => source.to_string(),
13441347
GlobImport { .. } => "*".to_string(),
1345-
ExternCrate(_) => "<extern crate>".to_string(),
1348+
ExternCrate { .. } => "<extern crate>".to_string(),
13461349
MacroUse => "#[macro_use]".to_string(),
13471350
}
13481351
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2018 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+
mod foo {
12+
pub struct A;
13+
pub struct B;
14+
}
15+
16+
use foo::{self};
17+
18+
use foo as self;
19+
20+
use foo::self;
21+
22+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error: expected identifier, found keyword `self`
2+
--> $DIR/import-self.rs:18:12
3+
|
4+
LL | use foo as self;
5+
| ^^^^ expected identifier, found keyword
6+
7+
error[E0429]: `self` imports are only allowed within a { } list
8+
--> $DIR/import-self.rs:20:5
9+
|
10+
LL | use foo::self;
11+
| ^^^^^^^^^
12+
13+
error[E0255]: the name `foo` is defined multiple times
14+
--> $DIR/import-self.rs:16:11
15+
|
16+
LL | mod foo {
17+
| ------- previous definition of the module `foo` here
18+
...
19+
LL | use foo::{self};
20+
| ^^^^ `foo` reimported here
21+
|
22+
= note: `foo` must be defined only once in the type namespace of this module
23+
help: you can use `as` to change the binding name of the import
24+
|
25+
LL | use foo::{self as other_foo};
26+
| ^^^^^^^^^^^^^^^^^
27+
28+
error: aborting due to 3 previous errors
29+
30+
Some errors occurred: E0255, E0429.
31+
For more information about an error, try `rustc --explain E0255`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2018 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+
mod foo {
12+
pub struct A;
13+
pub struct B;
14+
}
15+
16+
use foo::{A, A};
17+
18+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0252]: the name `A` is defined multiple times
2+
--> $DIR/import-twice.rs:16:14
3+
|
4+
LL | use foo::{A, A};
5+
| - ^ `A` reimported here
6+
| |
7+
| previous import of the type `A` here
8+
|
9+
= note: `A` must be defined only once in the type namespace of this module
10+
help: you can use `as` to change the binding name of the import
11+
|
12+
LL | use foo::{A, A as OtherA};
13+
| ^^^^^^^^^^^
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0252`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2018 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:issue_45829_a.rs
12+
// aux-build:issue_45829_b.rs
13+
14+
extern crate issue_45829_a;
15+
extern crate issue_45829_b as issue_45829_a;
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0259]: the name `issue_45829_a` is defined multiple times
2+
--> $DIR/rename-extern-with-tab.rs:15:1
3+
|
4+
LL | extern crate issue_45829_a;
5+
| --------------------------- previous import of the extern crate `issue_45829_a` here
6+
LL | extern crate issue_45829_b as issue_45829_a;
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `issue_45829_a` reimported here
8+
|
9+
= note: `issue_45829_a` must be defined only once in the type namespace of this module
10+
help: you can use `as` to change the binding name of the import
11+
|
12+
LL | extern crate issue_45829_b as other_issue_45829_a;
13+
|
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0259`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2018 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+
mod foo {
12+
pub struct A;
13+
14+
pub mod bar {
15+
pub struct B;
16+
}
17+
}
18+
19+
use foo::{A, bar::B as A};
20+
21+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0252]: the name `A` is defined multiple times
2+
--> $DIR/rename-use-with-tabs.rs:19:14
3+
|
4+
LL | use foo::{A, bar::B as A};
5+
| - ^^^^^^^^^^^^^^^^^ `A` reimported here
6+
| |
7+
| previous import of the type `A` here
8+
|
9+
= note: `A` must be defined only once in the type namespace of this module
10+
help: you can use `as` to change the binding name of the import
11+
|
12+
LL | use foo::{A, bar::B as OtherA};
13+
| ^^^^^^^^^^^^^^^^
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0252`.

src/test/ui/resolve/resolve-conflict-item-vs-extern-crate.stderr

-4
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@ LL | mod std {} //~ ERROR the name `std` is defined multiple times
55
| ^^^^^^^ `std` redefined here
66
|
77
= note: `std` must be defined only once in the type namespace of this module
8-
help: you can use `as` to change the binding name of the import
9-
|
10-
LL | as other_std// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
11-
| ^^^^^^^^^^^^
128

139
error: aborting due to previous error
1410

0 commit comments

Comments
 (0)