manage cases with tabs or other whitespaces

This commit is contained in:
François Mockers 2018-10-21 00:23:29 +02:00
parent 4520b305ec
commit 9eacd68a49
13 changed files with 204 additions and 29 deletions

View File

@ -449,7 +449,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
id: item.id, id: item.id,
parent, parent,
imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))), imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
subclass: ImportDirectiveSubclass::ExternCrate(orig_name), subclass: ImportDirectiveSubclass::ExternCrate {
source: orig_name,
target: ident,
},
root_span: item.span, root_span: item.span,
span: item.span, span: item.span,
module_path: Vec::new(), module_path: Vec::new(),

View File

@ -144,7 +144,7 @@ pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
} }
} }
} }
ImportDirectiveSubclass::ExternCrate(_) => { ImportDirectiveSubclass::ExternCrate { .. } => {
resolver.maybe_unused_extern_crates.push((directive.id, directive.span)); resolver.maybe_unused_extern_crates.push((directive.id, directive.span));
} }
ImportDirectiveSubclass::MacroUse => { ImportDirectiveSubclass::MacroUse => {

View File

@ -1234,7 +1234,7 @@ impl<'a> NameBinding<'a> {
match self.kind { match self.kind {
NameBindingKind::Import { NameBindingKind::Import {
directive: &ImportDirective { directive: &ImportDirective {
subclass: ImportDirectiveSubclass::ExternCrate(_), .. subclass: ImportDirectiveSubclass::ExternCrate { .. }, ..
}, .. }, ..
} => true, } => true,
_ => false, _ => false,
@ -3794,7 +3794,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
if let NameBindingKind::Import { directive: d, .. } = binding.kind { if let NameBindingKind::Import { directive: d, .. } = binding.kind {
// Careful: we still want to rewrite paths from // Careful: we still want to rewrite paths from
// renamed extern crates. // renamed extern crates.
if let ImportDirectiveSubclass::ExternCrate(None) = d.subclass { if let ImportDirectiveSubclass::ExternCrate { source: None, .. } = d.subclass {
return return
} }
} }
@ -4776,7 +4776,15 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
let cm = self.session.source_map(); let cm = self.session.source_map();
let rename_msg = "you can use `as` to change the binding name of the import"; let rename_msg = "you can use `as` to change the binding name of the import";
if let Ok(snippet) = cm.span_to_snippet(binding.span) { if let (
Ok(snippet),
NameBindingKind::Import { directive, ..},
_x @ 1 ... std::u32::MAX,
) = (
cm.span_to_snippet(binding.span),
binding.kind.clone(),
binding.span.hi().0,
) {
let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() { let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() {
format!("Other{}", name) format!("Other{}", name)
} else { } else {
@ -4785,24 +4793,29 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
err.span_suggestion_with_applicability( err.span_suggestion_with_applicability(
binding.span, binding.span,
rename_msg, &rename_msg,
match ( match (&directive.subclass, snippet.ends_with(";"), snippet.as_ref()) {
snippet.split_whitespace().find(|w| *w == "as"), (ImportDirectiveSubclass::SingleImport { .. }, false, "self") =>
snippet.ends_with(";") format!("self as {}", suggested_name),
) { (ImportDirectiveSubclass::SingleImport { source, .. }, false, _) =>
(Some(_), false) => format!("{} as {}", format!(
&snippet[..snippet.find(" as ").unwrap()], "{} as {}",
suggested_name, &snippet[..((source.span.hi().0 - binding.span.lo().0) as usize)],
), suggested_name,
(Some(_), true) => format!("{} as {};", ),
&snippet[..snippet.find(" as ").unwrap()], (ImportDirectiveSubclass::SingleImport { source, .. }, true, _) =>
suggested_name, format!(
), "{} as {};",
(None, false) => format!("{} as {}", snippet, suggested_name), &snippet[..((source.span.hi().0 - binding.span.lo().0) as usize)],
(None, true) => format!("{} as {};", suggested_name,
&snippet[..snippet.len() - 1], ),
suggested_name (ImportDirectiveSubclass::ExternCrate { source, target, .. }, _, _) =>
), format!(
"extern crate {} as {};",
source.unwrap_or(target.name),
suggested_name,
),
(_, _, _) => unreachable!(),
}, },
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
); );

View File

@ -52,7 +52,10 @@ pub enum ImportDirectiveSubclass<'a> {
max_vis: Cell<ty::Visibility>, // The visibility of the greatest re-export. max_vis: Cell<ty::Visibility>, // The visibility of the greatest re-export.
// n.b. `max_vis` is only used in `finalize_import` to check for re-export errors. // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors.
}, },
ExternCrate(Option<Name>), ExternCrate {
source: Option<Name>,
target: Ident,
},
MacroUse, MacroUse,
} }
@ -1342,7 +1345,7 @@ fn import_directive_subclass_to_string(subclass: &ImportDirectiveSubclass) -> St
match *subclass { match *subclass {
SingleImport { source, .. } => source.to_string(), SingleImport { source, .. } => source.to_string(),
GlobImport { .. } => "*".to_string(), GlobImport { .. } => "*".to_string(),
ExternCrate(_) => "<extern crate>".to_string(), ExternCrate { .. } => "<extern crate>".to_string(),
MacroUse => "#[macro_use]".to_string(), MacroUse => "#[macro_use]".to_string(),
} }
} }

View File

@ -0,0 +1,22 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
mod foo {
pub struct A;
pub struct B;
}
use foo::{self};
use foo as self;
use foo::self;
fn main() {}

View File

@ -0,0 +1,31 @@
error: expected identifier, found keyword `self`
--> $DIR/import-self.rs:18:12
|
LL | use foo as self;
| ^^^^ expected identifier, found keyword
error[E0429]: `self` imports are only allowed within a { } list
--> $DIR/import-self.rs:20:5
|
LL | use foo::self;
| ^^^^^^^^^
error[E0255]: the name `foo` is defined multiple times
--> $DIR/import-self.rs:16:11
|
LL | mod foo {
| ------- previous definition of the module `foo` here
...
LL | use foo::{self};
| ^^^^ `foo` reimported here
|
= note: `foo` must be defined only once in the type namespace of this module
help: you can use `as` to change the binding name of the import
|
LL | use foo::{self as other_foo};
| ^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors
Some errors occurred: E0255, E0429.
For more information about an error, try `rustc --explain E0255`.

View File

@ -0,0 +1,18 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
mod foo {
pub struct A;
pub struct B;
}
use foo::{A, A};
fn main() {}

View File

@ -0,0 +1,17 @@
error[E0252]: the name `A` is defined multiple times
--> $DIR/import-twice.rs:16:14
|
LL | use foo::{A, A};
| - ^ `A` reimported here
| |
| previous import of the type `A` here
|
= note: `A` must be defined only once in the type namespace of this module
help: you can use `as` to change the binding name of the import
|
LL | use foo::{A, A as OtherA};
| ^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0252`.

View File

@ -0,0 +1,17 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// aux-build:issue_45829_a.rs
// aux-build:issue_45829_b.rs
extern crate issue_45829_a;
extern crate issue_45829_b as issue_45829_a;
fn main() {}

View File

@ -0,0 +1,17 @@
error[E0259]: the name `issue_45829_a` is defined multiple times
--> $DIR/rename-extern-with-tab.rs:15:1
|
LL | extern crate issue_45829_a;
| --------------------------- previous import of the extern crate `issue_45829_a` here
LL | extern crate issue_45829_b as issue_45829_a;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `issue_45829_a` reimported here
|
= note: `issue_45829_a` must be defined only once in the type namespace of this module
help: you can use `as` to change the binding name of the import
|
LL | extern crate issue_45829_b as other_issue_45829_a;
|
error: aborting due to previous error
For more information about this error, try `rustc --explain E0259`.

View File

@ -0,0 +1,21 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
mod foo {
pub struct A;
pub mod bar {
pub struct B;
}
}
use foo::{A, bar::B as A};
fn main() {}

View File

@ -0,0 +1,17 @@
error[E0252]: the name `A` is defined multiple times
--> $DIR/rename-use-with-tabs.rs:19:14
|
LL | use foo::{A, bar::B as A};
| - ^^^^^^^^^^^^^^^^^ `A` reimported here
| |
| previous import of the type `A` here
|
= note: `A` must be defined only once in the type namespace of this module
help: you can use `as` to change the binding name of the import
|
LL | use foo::{A, bar::B as OtherA};
| ^^^^^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0252`.

View File

@ -5,10 +5,6 @@ LL | mod std {} //~ ERROR the name `std` is defined multiple times
| ^^^^^^^ `std` redefined here | ^^^^^^^ `std` redefined here
| |
= note: `std` must be defined only once in the type namespace of this module = note: `std` must be defined only once in the type namespace of this module
help: you can use `as` to change the binding name of the import
|
LL | as other_std// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
| ^^^^^^^^^^^^
error: aborting due to previous error error: aborting due to previous error