Add suggestion for duplicated import.
This commit adds a suggestion when a import is duplicated (ie. the same name is used twice trying to import the same thing) to remove the second import.
This commit is contained in:
parent
a21bd75688
commit
1595163356
18 changed files with 570 additions and 111 deletions
|
@ -238,12 +238,14 @@ impl<'a> Resolver<'a> {
|
||||||
macro_ns: Cell::new(None),
|
macro_ns: Cell::new(None),
|
||||||
},
|
},
|
||||||
type_ns_only,
|
type_ns_only,
|
||||||
|
nested,
|
||||||
};
|
};
|
||||||
self.add_import_directive(
|
self.add_import_directive(
|
||||||
module_path,
|
module_path,
|
||||||
subclass,
|
subclass,
|
||||||
use_tree.span,
|
use_tree.span,
|
||||||
id,
|
id,
|
||||||
|
item,
|
||||||
root_span,
|
root_span,
|
||||||
item.id,
|
item.id,
|
||||||
vis,
|
vis,
|
||||||
|
@ -260,6 +262,7 @@ impl<'a> Resolver<'a> {
|
||||||
subclass,
|
subclass,
|
||||||
use_tree.span,
|
use_tree.span,
|
||||||
id,
|
id,
|
||||||
|
item,
|
||||||
root_span,
|
root_span,
|
||||||
item.id,
|
item.id,
|
||||||
vis,
|
vis,
|
||||||
|
@ -379,6 +382,9 @@ impl<'a> Resolver<'a> {
|
||||||
source: orig_name,
|
source: orig_name,
|
||||||
target: ident,
|
target: ident,
|
||||||
},
|
},
|
||||||
|
has_attributes: !item.attrs.is_empty(),
|
||||||
|
use_span_with_attributes: item.span_with_attributes(),
|
||||||
|
use_span: item.span,
|
||||||
root_span: item.span,
|
root_span: item.span,
|
||||||
span: item.span,
|
span: item.span,
|
||||||
module_path: Vec::new(),
|
module_path: Vec::new(),
|
||||||
|
@ -824,6 +830,9 @@ impl<'a> Resolver<'a> {
|
||||||
parent_scope: parent_scope.clone(),
|
parent_scope: parent_scope.clone(),
|
||||||
imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
|
imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
|
||||||
subclass: ImportDirectiveSubclass::MacroUse,
|
subclass: ImportDirectiveSubclass::MacroUse,
|
||||||
|
use_span_with_attributes: item.span_with_attributes(),
|
||||||
|
has_attributes: !item.attrs.is_empty(),
|
||||||
|
use_span: item.span,
|
||||||
root_span: span,
|
root_span: span,
|
||||||
span,
|
span,
|
||||||
module_path: Vec::new(),
|
module_path: Vec::new(),
|
||||||
|
|
|
@ -63,7 +63,7 @@ use syntax::ast::{Label, Local, Mutability, Pat, PatKind, Path};
|
||||||
use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind};
|
use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind};
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
|
|
||||||
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
|
use syntax_pos::{BytePos, Span, DUMMY_SP, MultiSpan};
|
||||||
use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
|
use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
|
||||||
|
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
|
@ -1228,6 +1228,16 @@ enum NameBindingKind<'a> {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> NameBindingKind<'a> {
|
||||||
|
/// Is this a name binding of a import?
|
||||||
|
fn is_import(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
NameBindingKind::Import { .. } => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct PrivacyError<'a>(Span, Ident, &'a NameBinding<'a>);
|
struct PrivacyError<'a>(Span, Ident, &'a NameBinding<'a>);
|
||||||
|
|
||||||
struct UseError<'a> {
|
struct UseError<'a> {
|
||||||
|
@ -5134,66 +5144,237 @@ impl<'a> Resolver<'a> {
|
||||||
);
|
);
|
||||||
|
|
||||||
// See https://github.com/rust-lang/rust/issues/32354
|
// See https://github.com/rust-lang/rust/issues/32354
|
||||||
|
use NameBindingKind::Import;
|
||||||
let directive = match (&new_binding.kind, &old_binding.kind) {
|
let directive = match (&new_binding.kind, &old_binding.kind) {
|
||||||
(NameBindingKind::Import { directive, .. }, _) if !new_binding.span.is_dummy() =>
|
// If there are two imports where one or both have attributes then prefer removing the
|
||||||
Some((directive, new_binding.span)),
|
// import without attributes.
|
||||||
(_, NameBindingKind::Import { directive, .. }) if !old_binding.span.is_dummy() =>
|
(Import { directive: new, .. }, Import { directive: old, .. }) if {
|
||||||
Some((directive, old_binding.span)),
|
!new_binding.span.is_dummy() && !old_binding.span.is_dummy() &&
|
||||||
|
(new.has_attributes || old.has_attributes)
|
||||||
|
} => {
|
||||||
|
if old.has_attributes {
|
||||||
|
Some((new, new_binding.span, true))
|
||||||
|
} else {
|
||||||
|
Some((old, old_binding.span, true))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Otherwise prioritize the new binding.
|
||||||
|
(Import { directive, .. }, other) if !new_binding.span.is_dummy() =>
|
||||||
|
Some((directive, new_binding.span, other.is_import())),
|
||||||
|
(other, Import { directive, .. }) if !old_binding.span.is_dummy() =>
|
||||||
|
Some((directive, old_binding.span, other.is_import())),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
if let Some((directive, binding_span)) = directive {
|
|
||||||
let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() {
|
|
||||||
format!("Other{}", name)
|
|
||||||
} else {
|
|
||||||
format!("other_{}", name)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut suggestion = None;
|
// Check if the target of the use for both bindings is the same.
|
||||||
match directive.subclass {
|
let duplicate = new_binding.def().opt_def_id() == old_binding.def().opt_def_id();
|
||||||
ImportDirectiveSubclass::SingleImport { type_ns_only: true, .. } =>
|
let has_dummy_span = new_binding.span.is_dummy() || old_binding.span.is_dummy();
|
||||||
suggestion = Some(format!("self as {}", suggested_name)),
|
let from_item = self.extern_prelude.get(&ident)
|
||||||
ImportDirectiveSubclass::SingleImport { source, .. } => {
|
.map(|entry| entry.introduced_by_item)
|
||||||
if let Some(pos) = source.span.hi().0.checked_sub(binding_span.lo().0)
|
.unwrap_or(true);
|
||||||
.map(|pos| pos as usize) {
|
// Only suggest removing an import if both bindings are to the same def, if both spans
|
||||||
if let Ok(snippet) = self.session.source_map()
|
// aren't dummy spans. Further, if both bindings are imports, then the ident must have
|
||||||
.span_to_snippet(binding_span) {
|
// been introduced by a item.
|
||||||
if pos <= snippet.len() {
|
let should_remove_import = duplicate && !has_dummy_span &&
|
||||||
suggestion = Some(format!(
|
((new_binding.is_extern_crate() || old_binding.is_extern_crate()) || from_item);
|
||||||
"{} as {}{}",
|
|
||||||
&snippet[..pos],
|
|
||||||
suggested_name,
|
|
||||||
if snippet.ends_with(";") { ";" } else { "" }
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImportDirectiveSubclass::ExternCrate { source, target, .. } =>
|
|
||||||
suggestion = Some(format!(
|
|
||||||
"extern crate {} as {};",
|
|
||||||
source.unwrap_or(target.name),
|
|
||||||
suggested_name,
|
|
||||||
)),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
|
|
||||||
let rename_msg = "you can use `as` to change the binding name of the import";
|
match directive {
|
||||||
if let Some(suggestion) = suggestion {
|
Some((directive, span, true)) if should_remove_import && directive.is_nested() =>
|
||||||
|
self.add_suggestion_for_duplicate_nested_use(&mut err, directive, span),
|
||||||
|
Some((directive, _, true)) if should_remove_import && !directive.is_glob() => {
|
||||||
|
// Simple case - remove the entire import. Due to the above match arm, this can
|
||||||
|
// only be a single use so just remove it entirely.
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
binding_span,
|
directive.use_span_with_attributes,
|
||||||
rename_msg,
|
"remove unnecessary import",
|
||||||
suggestion,
|
String::new(),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
} else {
|
},
|
||||||
err.span_label(binding_span, rename_msg);
|
Some((directive, span, _)) =>
|
||||||
}
|
self.add_suggestion_for_rename_of_use(&mut err, name, directive, span),
|
||||||
|
_ => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
err.emit();
|
err.emit();
|
||||||
self.name_already_seen.insert(name, span);
|
self.name_already_seen.insert(name, span);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This function adds a suggestion to change the binding name of a new import that conflicts
|
||||||
|
/// with an existing import.
|
||||||
|
///
|
||||||
|
/// ```ignore (diagnostic)
|
||||||
|
/// help: you can use `as` to change the binding name of the import
|
||||||
|
/// |
|
||||||
|
/// LL | use foo::bar as other_bar;
|
||||||
|
/// | ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
/// ```
|
||||||
|
fn add_suggestion_for_rename_of_use(
|
||||||
|
&self,
|
||||||
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
|
name: Symbol,
|
||||||
|
directive: &ImportDirective<'_>,
|
||||||
|
binding_span: Span,
|
||||||
|
) {
|
||||||
|
let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() {
|
||||||
|
format!("Other{}", name)
|
||||||
|
} else {
|
||||||
|
format!("other_{}", name)
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut suggestion = None;
|
||||||
|
match directive.subclass {
|
||||||
|
ImportDirectiveSubclass::SingleImport { type_ns_only: true, .. } =>
|
||||||
|
suggestion = Some(format!("self as {}", suggested_name)),
|
||||||
|
ImportDirectiveSubclass::SingleImport { source, .. } => {
|
||||||
|
if let Some(pos) = source.span.hi().0.checked_sub(binding_span.lo().0)
|
||||||
|
.map(|pos| pos as usize) {
|
||||||
|
if let Ok(snippet) = self.session.source_map()
|
||||||
|
.span_to_snippet(binding_span) {
|
||||||
|
if pos <= snippet.len() {
|
||||||
|
suggestion = Some(format!(
|
||||||
|
"{} as {}{}",
|
||||||
|
&snippet[..pos],
|
||||||
|
suggested_name,
|
||||||
|
if snippet.ends_with(";") { ";" } else { "" }
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImportDirectiveSubclass::ExternCrate { source, target, .. } =>
|
||||||
|
suggestion = Some(format!(
|
||||||
|
"extern crate {} as {};",
|
||||||
|
source.unwrap_or(target.name),
|
||||||
|
suggested_name,
|
||||||
|
)),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
let rename_msg = "you can use `as` to change the binding name of the import";
|
||||||
|
if let Some(suggestion) = suggestion {
|
||||||
|
err.span_suggestion(
|
||||||
|
binding_span,
|
||||||
|
rename_msg,
|
||||||
|
suggestion,
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
err.span_label(binding_span, rename_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This function adds a suggestion to remove a unnecessary binding from an import that is
|
||||||
|
/// nested. In the following example, this function will be invoked to remove the `a` binding
|
||||||
|
/// in the second use statement:
|
||||||
|
///
|
||||||
|
/// ```ignore (diagnostic)
|
||||||
|
/// use issue_52891::a;
|
||||||
|
/// use issue_52891::{d, a, e};
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// The following suggestion will be added:
|
||||||
|
///
|
||||||
|
/// ```ignore (diagnostic)
|
||||||
|
/// use issue_52891::{d, a, e};
|
||||||
|
/// ^-- help: remove unnecessary import
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// If the nested use contains only one import then the suggestion will remove the entire
|
||||||
|
/// line.
|
||||||
|
///
|
||||||
|
/// It is expected that the directive provided is a nested import - this isn't checked by the
|
||||||
|
/// function. If this invariant is not upheld, this function's behaviour will be unexpected
|
||||||
|
/// as characters expected by span manipulations won't be present.
|
||||||
|
fn add_suggestion_for_duplicate_nested_use(
|
||||||
|
&self,
|
||||||
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
|
directive: &ImportDirective<'_>,
|
||||||
|
binding_span: Span,
|
||||||
|
) {
|
||||||
|
assert!(directive.is_nested());
|
||||||
|
let message = "remove unnecessary import";
|
||||||
|
let source_map = self.session.source_map();
|
||||||
|
|
||||||
|
// Two examples will be used to illustrate the span manipulations we're doing:
|
||||||
|
//
|
||||||
|
// - Given `use issue_52891::{d, a, e};` where `a` is a duplicate then `binding_span` is
|
||||||
|
// `a` and `directive.use_span` is `issue_52891::{d, a, e};`.
|
||||||
|
// - Given `use issue_52891::{d, e, a};` where `a` is a duplicate then `binding_span` is
|
||||||
|
// `a` and `directive.use_span` is `issue_52891::{d, e, a};`.
|
||||||
|
|
||||||
|
// Find the span of everything after the binding.
|
||||||
|
// ie. `a, e};` or `a};`
|
||||||
|
let binding_until_end = binding_span.with_hi(directive.use_span.hi());
|
||||||
|
|
||||||
|
// Find everything after the binding but not including the binding.
|
||||||
|
// ie. `, e};` or `};`
|
||||||
|
let after_binding_until_end = binding_until_end.with_lo(binding_span.hi());
|
||||||
|
|
||||||
|
// Keep characters in the span until we encounter something that isn't a comma or
|
||||||
|
// whitespace.
|
||||||
|
// ie. `, ` or ``.
|
||||||
|
//
|
||||||
|
// Also note whether a closing brace character was encountered. If there
|
||||||
|
// was, then later go backwards to remove any trailing commas that are left.
|
||||||
|
let mut found_closing_brace = false;
|
||||||
|
let after_binding_until_next_binding = source_map.span_take_while(
|
||||||
|
after_binding_until_end,
|
||||||
|
|&ch| {
|
||||||
|
if ch == '}' { found_closing_brace = true; }
|
||||||
|
ch == ' ' || ch == ','
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Combine the two spans.
|
||||||
|
// ie. `a, ` or `a`.
|
||||||
|
//
|
||||||
|
// Removing these would leave `issue_52891::{d, e};` or `issue_52891::{d, e, };`
|
||||||
|
let span = binding_span.with_hi(after_binding_until_next_binding.hi());
|
||||||
|
|
||||||
|
// If there was a closing brace then identify the span to remove any trailing commas from
|
||||||
|
// previous imports.
|
||||||
|
if found_closing_brace {
|
||||||
|
if let Ok(prev_source) = source_map.span_to_prev_source(span) {
|
||||||
|
// `prev_source` will contain all of the source that came before the span.
|
||||||
|
// Then split based on a command and take the first (ie. closest to our span)
|
||||||
|
// snippet. In the example, this is a space.
|
||||||
|
let prev_comma = prev_source.rsplit(',').collect::<Vec<_>>();
|
||||||
|
let prev_starting_brace = prev_source.rsplit('{').collect::<Vec<_>>();
|
||||||
|
if prev_comma.len() > 1 && prev_starting_brace.len() > 1 {
|
||||||
|
let prev_comma = prev_comma.first().unwrap();
|
||||||
|
let prev_starting_brace = prev_starting_brace.first().unwrap();
|
||||||
|
|
||||||
|
// If the amount of source code before the comma is greater than
|
||||||
|
// the amount of source code before the starting brace then we've only
|
||||||
|
// got one item in the nested item (eg. `issue_52891::{self}`).
|
||||||
|
if prev_comma.len() > prev_starting_brace.len() {
|
||||||
|
// So just remove the entire line...
|
||||||
|
err.span_suggestion(
|
||||||
|
directive.use_span_with_attributes,
|
||||||
|
message,
|
||||||
|
String::new(),
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let span = span.with_lo(BytePos(
|
||||||
|
// Take away the number of bytes for the characters we've found and an
|
||||||
|
// extra for the comma.
|
||||||
|
span.lo().0 - (prev_comma.as_bytes().len() as u32) - 1
|
||||||
|
));
|
||||||
|
err.span_suggestion(
|
||||||
|
span, message, String::new(), Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err.span_suggestion(span, message, String::new(), Applicability::MachineApplicable);
|
||||||
|
}
|
||||||
|
|
||||||
fn extern_prelude_get(&mut self, ident: Ident, speculative: bool)
|
fn extern_prelude_get(&mut self, ident: Ident, speculative: bool)
|
||||||
-> Option<&'a NameBinding<'a>> {
|
-> Option<&'a NameBinding<'a>> {
|
||||||
if ident.is_path_segment_keyword() {
|
if ident.is_path_segment_keyword() {
|
||||||
|
|
|
@ -18,7 +18,7 @@ use rustc::hir::def::*;
|
||||||
use rustc::session::DiagnosticMessageId;
|
use rustc::session::DiagnosticMessageId;
|
||||||
use rustc::util::nodemap::FxHashSet;
|
use rustc::util::nodemap::FxHashSet;
|
||||||
|
|
||||||
use syntax::ast::{Ident, Name, NodeId, CRATE_NODE_ID};
|
use syntax::ast::{self, Ident, Name, NodeId, CRATE_NODE_ID};
|
||||||
use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
|
use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
|
||||||
use syntax::ext::hygiene::Mark;
|
use syntax::ext::hygiene::Mark;
|
||||||
use syntax::symbol::keywords;
|
use syntax::symbol::keywords;
|
||||||
|
@ -42,6 +42,8 @@ pub enum ImportDirectiveSubclass<'a> {
|
||||||
target_bindings: PerNS<Cell<Option<&'a NameBinding<'a>>>>,
|
target_bindings: PerNS<Cell<Option<&'a NameBinding<'a>>>>,
|
||||||
/// `true` for `...::{self [as target]}` imports, `false` otherwise.
|
/// `true` for `...::{self [as target]}` imports, `false` otherwise.
|
||||||
type_ns_only: bool,
|
type_ns_only: bool,
|
||||||
|
/// Did this import result from a nested import? ie. `use foo::{bar, baz};`
|
||||||
|
nested: bool,
|
||||||
},
|
},
|
||||||
GlobImport {
|
GlobImport {
|
||||||
is_prelude: bool,
|
is_prelude: bool,
|
||||||
|
@ -78,6 +80,15 @@ crate struct ImportDirective<'a> {
|
||||||
/// `UseTree` node.
|
/// `UseTree` node.
|
||||||
pub root_id: NodeId,
|
pub root_id: NodeId,
|
||||||
|
|
||||||
|
/// Span of the entire use statement.
|
||||||
|
pub use_span: Span,
|
||||||
|
|
||||||
|
/// Span of the entire use statement with attributes.
|
||||||
|
pub use_span_with_attributes: Span,
|
||||||
|
|
||||||
|
/// Did the use statement have any attributes?
|
||||||
|
pub has_attributes: bool,
|
||||||
|
|
||||||
/// Span of this use tree.
|
/// Span of this use tree.
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
|
||||||
|
@ -98,6 +109,13 @@ impl<'a> ImportDirective<'a> {
|
||||||
match self.subclass { ImportDirectiveSubclass::GlobImport { .. } => true, _ => false }
|
match self.subclass { ImportDirectiveSubclass::GlobImport { .. } => true, _ => false }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_nested(&self) -> bool {
|
||||||
|
match self.subclass {
|
||||||
|
ImportDirectiveSubclass::SingleImport { nested, .. } => nested,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
crate fn crate_lint(&self) -> CrateLint {
|
crate fn crate_lint(&self) -> CrateLint {
|
||||||
CrateLint::UsePath { root_id: self.root_id, root_span: self.root_span }
|
CrateLint::UsePath { root_id: self.root_id, root_span: self.root_span }
|
||||||
}
|
}
|
||||||
|
@ -390,6 +408,7 @@ impl<'a> Resolver<'a> {
|
||||||
subclass: ImportDirectiveSubclass<'a>,
|
subclass: ImportDirectiveSubclass<'a>,
|
||||||
span: Span,
|
span: Span,
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
|
item: &ast::Item,
|
||||||
root_span: Span,
|
root_span: Span,
|
||||||
root_id: NodeId,
|
root_id: NodeId,
|
||||||
vis: ty::Visibility,
|
vis: ty::Visibility,
|
||||||
|
@ -402,6 +421,9 @@ impl<'a> Resolver<'a> {
|
||||||
subclass,
|
subclass,
|
||||||
span,
|
span,
|
||||||
id,
|
id,
|
||||||
|
use_span: item.span,
|
||||||
|
use_span_with_attributes: item.span_with_attributes(),
|
||||||
|
has_attributes: !item.attrs.is_empty(),
|
||||||
root_span,
|
root_span,
|
||||||
root_id,
|
root_id,
|
||||||
vis: Cell::new(vis),
|
vis: Cell::new(vis),
|
||||||
|
@ -787,7 +809,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||||
let (source, target, source_bindings, target_bindings, type_ns_only) =
|
let (source, target, source_bindings, target_bindings, type_ns_only) =
|
||||||
match directive.subclass {
|
match directive.subclass {
|
||||||
SingleImport { source, target, ref source_bindings,
|
SingleImport { source, target, ref source_bindings,
|
||||||
ref target_bindings, type_ns_only } =>
|
ref target_bindings, type_ns_only, .. } =>
|
||||||
(source, target, source_bindings, target_bindings, type_ns_only),
|
(source, target, source_bindings, target_bindings, type_ns_only),
|
||||||
GlobImport { .. } => {
|
GlobImport { .. } => {
|
||||||
self.resolve_glob_import(directive);
|
self.resolve_glob_import(directive);
|
||||||
|
@ -908,7 +930,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||||
let (ident, target, source_bindings, target_bindings, type_ns_only) =
|
let (ident, target, source_bindings, target_bindings, type_ns_only) =
|
||||||
match directive.subclass {
|
match directive.subclass {
|
||||||
SingleImport { source, target, ref source_bindings,
|
SingleImport { source, target, ref source_bindings,
|
||||||
ref target_bindings, type_ns_only } =>
|
ref target_bindings, type_ns_only, .. } =>
|
||||||
(source, target, source_bindings, target_bindings, type_ns_only),
|
(source, target, source_bindings, target_bindings, type_ns_only),
|
||||||
GlobImport { is_prelude, ref max_vis } => {
|
GlobImport { is_prelude, ref max_vis } => {
|
||||||
if directive.module_path.len() <= 1 {
|
if directive.module_path.len() <= 1 {
|
||||||
|
|
|
@ -2164,6 +2164,13 @@ pub struct Item {
|
||||||
pub tokens: Option<TokenStream>,
|
pub tokens: Option<TokenStream>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Item {
|
||||||
|
/// Return the span that encompasses the attributes.
|
||||||
|
pub fn span_with_attributes(&self) -> Span {
|
||||||
|
self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A function header.
|
/// A function header.
|
||||||
///
|
///
|
||||||
/// All the information between the visibility and the name of the function is
|
/// All the information between the visibility and the name of the function is
|
||||||
|
|
|
@ -4,13 +4,12 @@ error[E0252]: the name `X` is defined multiple times
|
||||||
LL | pub use self::bar::X;
|
LL | pub use self::bar::X;
|
||||||
| ------------ previous import of the type `X` here
|
| ------------ previous import of the type `X` here
|
||||||
LL | use self::bar::X;
|
LL | use self::bar::X;
|
||||||
| ^^^^^^^^^^^^ `X` reimported here
|
| ----^^^^^^^^^^^^-
|
||||||
|
| | |
|
||||||
|
| | `X` reimported here
|
||||||
|
| help: remove unnecessary import
|
||||||
|
|
|
|
||||||
= note: `X` must be defined only once in the type namespace of this module
|
= note: `X` 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 self::bar::X as OtherX;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -10,15 +10,13 @@ error[E0252]: the name `fmt` is defined multiple times
|
||||||
--> $DIR/E0430.rs:1:22
|
--> $DIR/E0430.rs:1:22
|
||||||
|
|
|
|
||||||
LL | use std::fmt::{self, self}; //~ ERROR E0430
|
LL | use std::fmt::{self, self}; //~ ERROR E0430
|
||||||
| ---- ^^^^ `fmt` reimported here
|
| ------^^^^
|
||||||
| |
|
| | | |
|
||||||
|
| | | `fmt` reimported here
|
||||||
|
| | help: remove unnecessary import
|
||||||
| previous import of the module `fmt` here
|
| previous import of the module `fmt` here
|
||||||
|
|
|
|
||||||
= note: `fmt` must be defined only once in the type namespace of this module
|
= note: `fmt` 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 std::fmt::{self, self as other_fmt}; //~ ERROR E0430
|
|
||||||
| ^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,12 @@ error[E0252]: the name `foo` is defined multiple times
|
||||||
LL | use a::foo;
|
LL | use a::foo;
|
||||||
| ------ previous import of the value `foo` here
|
| ------ previous import of the value `foo` here
|
||||||
LL | use a::foo; //~ ERROR the name `foo` is defined multiple times
|
LL | use a::foo; //~ ERROR the name `foo` is defined multiple times
|
||||||
| ^^^^^^ `foo` reimported here
|
| ----^^^^^^-
|
||||||
|
| | |
|
||||||
|
| | `foo` reimported here
|
||||||
|
| help: remove unnecessary import
|
||||||
|
|
|
|
||||||
= note: `foo` must be defined only once in the value namespace of this module
|
= note: `foo` must be defined only once in the value namespace of this module
|
||||||
help: you can use `as` to change the binding name of the import
|
|
||||||
|
|
|
||||||
LL | use a::foo as other_foo; //~ ERROR the name `foo` is defined multiple times
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error[E0659]: `foo` is ambiguous (glob import vs glob import in the same module)
|
error[E0659]: `foo` is ambiguous (glob import vs glob import in the same module)
|
||||||
--> $DIR/duplicate.rs:46:15
|
--> $DIR/duplicate.rs:46:15
|
||||||
|
|
33
src/test/ui/issues/auxiliary/issue-52891.rs
Normal file
33
src/test/ui/issues/auxiliary/issue-52891.rs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
pub mod a {
|
||||||
|
pub mod inner {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod b {
|
||||||
|
pub mod inner {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod c {}
|
||||||
|
|
||||||
|
pub mod d {}
|
||||||
|
|
||||||
|
pub mod e {}
|
||||||
|
|
||||||
|
pub mod f {}
|
||||||
|
|
||||||
|
pub mod g {}
|
||||||
|
|
||||||
|
pub mod h {}
|
||||||
|
|
||||||
|
pub mod i {}
|
||||||
|
|
||||||
|
pub mod j {}
|
||||||
|
|
||||||
|
pub mod k {}
|
||||||
|
|
||||||
|
pub mod l {}
|
||||||
|
|
||||||
|
pub mod m {}
|
||||||
|
|
||||||
|
pub mod n {}
|
|
@ -4,13 +4,12 @@ error[E0252]: the name `Arc` is defined multiple times
|
||||||
LL | use std::sync::{self, Arc};
|
LL | use std::sync::{self, Arc};
|
||||||
| --- previous import of the type `Arc` here
|
| --- previous import of the type `Arc` here
|
||||||
LL | use std::sync::Arc; //~ ERROR the name `Arc` is defined multiple times
|
LL | use std::sync::Arc; //~ ERROR the name `Arc` is defined multiple times
|
||||||
| ^^^^^^^^^^^^^^ `Arc` reimported here
|
| ----^^^^^^^^^^^^^^-
|
||||||
|
| | |
|
||||||
|
| | `Arc` reimported here
|
||||||
|
| help: remove unnecessary import
|
||||||
|
|
|
|
||||||
= note: `Arc` must be defined only once in the type namespace of this module
|
= note: `Arc` 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 std::sync::Arc as OtherArc; //~ ERROR the name `Arc` is defined multiple times
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error[E0252]: the name `sync` is defined multiple times
|
error[E0252]: the name `sync` is defined multiple times
|
||||||
--> $DIR/issue-26886.rs:4:5
|
--> $DIR/issue-26886.rs:4:5
|
||||||
|
@ -19,13 +18,12 @@ LL | use std::sync::{self, Arc};
|
||||||
| ---- previous import of the module `sync` here
|
| ---- previous import of the module `sync` here
|
||||||
...
|
...
|
||||||
LL | use std::sync; //~ ERROR the name `sync` is defined multiple times
|
LL | use std::sync; //~ ERROR the name `sync` is defined multiple times
|
||||||
| ^^^^^^^^^ `sync` reimported here
|
| ----^^^^^^^^^-
|
||||||
|
| | |
|
||||||
|
| | `sync` reimported here
|
||||||
|
| help: remove unnecessary import
|
||||||
|
|
|
|
||||||
= note: `sync` must be defined only once in the type namespace of this module
|
= note: `sync` 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 std::sync as other_sync; //~ ERROR the name `sync` is defined multiple times
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,13 @@ error[E0252]: the name `A` is defined multiple times
|
||||||
--> $DIR/import-twice.rs:6:14
|
--> $DIR/import-twice.rs:6:14
|
||||||
|
|
|
|
||||||
LL | use foo::{A, A};
|
LL | use foo::{A, A};
|
||||||
| - ^ `A` reimported here
|
| ---^
|
||||||
| |
|
| || |
|
||||||
|
| || `A` reimported here
|
||||||
|
| |help: remove unnecessary import
|
||||||
| previous import of the type `A` here
|
| previous import of the type `A` here
|
||||||
|
|
|
|
||||||
= note: `A` must be defined only once in the type namespace of this module
|
= 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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
37
src/test/ui/issues/issue-52891.fixed
Normal file
37
src/test/ui/issues/issue-52891.fixed
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// aux-build:issue-52891.rs
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
#![allow(warnings)]
|
||||||
|
|
||||||
|
extern crate issue_52891;
|
||||||
|
|
||||||
|
// Check that we don't suggest renaming duplicate imports but instead
|
||||||
|
// suggest removing one.
|
||||||
|
|
||||||
|
use issue_52891::a;
|
||||||
|
//~ ERROR `a` is defined multiple times
|
||||||
|
|
||||||
|
use issue_52891::{b, c}; //~ ERROR `a` is defined multiple times
|
||||||
|
use issue_52891::{d, e}; //~ ERROR `a` is defined multiple times
|
||||||
|
use issue_52891::{f, g}; //~ ERROR `a` is defined multiple times
|
||||||
|
|
||||||
|
use issue_52891::{//~ ERROR `a` is defined multiple times
|
||||||
|
h,
|
||||||
|
i};
|
||||||
|
use issue_52891::{j,
|
||||||
|
//~ ERROR `a` is defined multiple times
|
||||||
|
k};
|
||||||
|
use issue_52891::{l,
|
||||||
|
m}; //~ ERROR `a` is defined multiple times
|
||||||
|
|
||||||
|
use issue_52891::a::inner;
|
||||||
|
use issue_52891::b::inner as other_inner; //~ ERROR `inner` is defined multiple times
|
||||||
|
|
||||||
|
|
||||||
|
//~^ ERROR `issue_52891` is defined multiple times
|
||||||
|
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
use issue_52891::n; //~ ERROR `n` is defined multiple times
|
||||||
|
|
||||||
|
fn main() {}
|
38
src/test/ui/issues/issue-52891.rs
Normal file
38
src/test/ui/issues/issue-52891.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// aux-build:issue-52891.rs
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
#![allow(warnings)]
|
||||||
|
|
||||||
|
extern crate issue_52891;
|
||||||
|
|
||||||
|
// Check that we don't suggest renaming duplicate imports but instead
|
||||||
|
// suggest removing one.
|
||||||
|
|
||||||
|
use issue_52891::a;
|
||||||
|
use issue_52891::a; //~ ERROR `a` is defined multiple times
|
||||||
|
|
||||||
|
use issue_52891::{a, b, c}; //~ ERROR `a` is defined multiple times
|
||||||
|
use issue_52891::{d, a, e}; //~ ERROR `a` is defined multiple times
|
||||||
|
use issue_52891::{f, g, a}; //~ ERROR `a` is defined multiple times
|
||||||
|
|
||||||
|
use issue_52891::{a, //~ ERROR `a` is defined multiple times
|
||||||
|
h,
|
||||||
|
i};
|
||||||
|
use issue_52891::{j,
|
||||||
|
a, //~ ERROR `a` is defined multiple times
|
||||||
|
k};
|
||||||
|
use issue_52891::{l,
|
||||||
|
m,
|
||||||
|
a}; //~ ERROR `a` is defined multiple times
|
||||||
|
|
||||||
|
use issue_52891::a::inner;
|
||||||
|
use issue_52891::b::inner; //~ ERROR `inner` is defined multiple times
|
||||||
|
|
||||||
|
use issue_52891::{self};
|
||||||
|
//~^ ERROR `issue_52891` is defined multiple times
|
||||||
|
|
||||||
|
use issue_52891::n;
|
||||||
|
#[macro_use]
|
||||||
|
use issue_52891::n; //~ ERROR `n` is defined multiple times
|
||||||
|
|
||||||
|
fn main() {}
|
145
src/test/ui/issues/issue-52891.stderr
Normal file
145
src/test/ui/issues/issue-52891.stderr
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
error[E0252]: the name `a` is defined multiple times
|
||||||
|
--> $DIR/issue-52891.rs:12:5
|
||||||
|
|
|
||||||
|
LL | use issue_52891::a;
|
||||||
|
| -------------- previous import of the module `a` here
|
||||||
|
LL | use issue_52891::a; //~ ERROR `a` is defined multiple times
|
||||||
|
| ----^^^^^^^^^^^^^^-
|
||||||
|
| | |
|
||||||
|
| | `a` reimported here
|
||||||
|
| help: remove unnecessary import
|
||||||
|
|
|
||||||
|
= note: `a` must be defined only once in the type namespace of this module
|
||||||
|
|
||||||
|
error[E0252]: the name `a` is defined multiple times
|
||||||
|
--> $DIR/issue-52891.rs:14:19
|
||||||
|
|
|
||||||
|
LL | use issue_52891::a;
|
||||||
|
| -------------- previous import of the module `a` here
|
||||||
|
...
|
||||||
|
LL | use issue_52891::{a, b, c}; //~ ERROR `a` is defined multiple times
|
||||||
|
| ^--
|
||||||
|
| |
|
||||||
|
| `a` reimported here
|
||||||
|
| help: remove unnecessary import
|
||||||
|
|
|
||||||
|
= note: `a` must be defined only once in the type namespace of this module
|
||||||
|
|
||||||
|
error[E0252]: the name `a` is defined multiple times
|
||||||
|
--> $DIR/issue-52891.rs:15:22
|
||||||
|
|
|
||||||
|
LL | use issue_52891::a;
|
||||||
|
| -------------- previous import of the module `a` here
|
||||||
|
...
|
||||||
|
LL | use issue_52891::{d, a, e}; //~ ERROR `a` is defined multiple times
|
||||||
|
| ^--
|
||||||
|
| |
|
||||||
|
| `a` reimported here
|
||||||
|
| help: remove unnecessary import
|
||||||
|
|
|
||||||
|
= note: `a` must be defined only once in the type namespace of this module
|
||||||
|
|
||||||
|
error[E0252]: the name `a` is defined multiple times
|
||||||
|
--> $DIR/issue-52891.rs:16:25
|
||||||
|
|
|
||||||
|
LL | use issue_52891::a;
|
||||||
|
| -------------- previous import of the module `a` here
|
||||||
|
...
|
||||||
|
LL | use issue_52891::{f, g, a}; //~ ERROR `a` is defined multiple times
|
||||||
|
| --^
|
||||||
|
| | |
|
||||||
|
| | `a` reimported here
|
||||||
|
| help: remove unnecessary import
|
||||||
|
|
|
||||||
|
= note: `a` must be defined only once in the type namespace of this module
|
||||||
|
|
||||||
|
error[E0252]: the name `a` is defined multiple times
|
||||||
|
--> $DIR/issue-52891.rs:18:19
|
||||||
|
|
|
||||||
|
LL | use issue_52891::a;
|
||||||
|
| -------------- previous import of the module `a` here
|
||||||
|
...
|
||||||
|
LL | use issue_52891::{a, //~ ERROR `a` is defined multiple times
|
||||||
|
| ^--
|
||||||
|
| |
|
||||||
|
| `a` reimported here
|
||||||
|
| help: remove unnecessary import
|
||||||
|
|
|
||||||
|
= note: `a` must be defined only once in the type namespace of this module
|
||||||
|
|
||||||
|
error[E0252]: the name `a` is defined multiple times
|
||||||
|
--> $DIR/issue-52891.rs:22:5
|
||||||
|
|
|
||||||
|
LL | use issue_52891::a;
|
||||||
|
| -------------- previous import of the module `a` here
|
||||||
|
...
|
||||||
|
LL | a, //~ ERROR `a` is defined multiple times
|
||||||
|
| ^--
|
||||||
|
| |
|
||||||
|
| `a` reimported here
|
||||||
|
| help: remove unnecessary import
|
||||||
|
|
|
||||||
|
= note: `a` must be defined only once in the type namespace of this module
|
||||||
|
|
||||||
|
error[E0252]: the name `a` is defined multiple times
|
||||||
|
--> $DIR/issue-52891.rs:26:5
|
||||||
|
|
|
||||||
|
LL | use issue_52891::a;
|
||||||
|
| -------------- previous import of the module `a` here
|
||||||
|
...
|
||||||
|
LL | m,
|
||||||
|
| ______-
|
||||||
|
LL | | a}; //~ ERROR `a` is defined multiple times
|
||||||
|
| | -
|
||||||
|
| | |
|
||||||
|
| |_____`a` reimported here
|
||||||
|
| help: remove unnecessary import
|
||||||
|
|
|
||||||
|
= note: `a` must be defined only once in the type namespace of this module
|
||||||
|
|
||||||
|
error[E0252]: the name `inner` is defined multiple times
|
||||||
|
--> $DIR/issue-52891.rs:29:5
|
||||||
|
|
|
||||||
|
LL | use issue_52891::a::inner;
|
||||||
|
| --------------------- previous import of the module `inner` here
|
||||||
|
LL | use issue_52891::b::inner; //~ ERROR `inner` is defined multiple times
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ `inner` reimported here
|
||||||
|
|
|
||||||
|
= note: `inner` 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 issue_52891::b::inner as other_inner; //~ ERROR `inner` is defined multiple times
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0254]: the name `issue_52891` is defined multiple times
|
||||||
|
--> $DIR/issue-52891.rs:31:19
|
||||||
|
|
|
||||||
|
LL | extern crate issue_52891;
|
||||||
|
| ------------------------- previous import of the extern crate `issue_52891` here
|
||||||
|
...
|
||||||
|
LL | use issue_52891::{self};
|
||||||
|
| ------------------^^^^--
|
||||||
|
| | |
|
||||||
|
| | `issue_52891` reimported here
|
||||||
|
| help: remove unnecessary import
|
||||||
|
|
|
||||||
|
= note: `issue_52891` must be defined only once in the type namespace of this module
|
||||||
|
|
||||||
|
error[E0252]: the name `n` is defined multiple times
|
||||||
|
--> $DIR/issue-52891.rs:36:5
|
||||||
|
|
|
||||||
|
LL | use issue_52891::n;
|
||||||
|
| -------------------
|
||||||
|
| | |
|
||||||
|
| | previous import of the module `n` here
|
||||||
|
| help: remove unnecessary import
|
||||||
|
LL | #[macro_use]
|
||||||
|
LL | use issue_52891::n; //~ ERROR `n` is defined multiple times
|
||||||
|
| ^^^^^^^^^^^^^^ `n` reimported here
|
||||||
|
|
|
||||||
|
= note: `n` must be defined only once in the type namespace of this module
|
||||||
|
|
||||||
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
|
Some errors occurred: E0252, E0254.
|
||||||
|
For more information about an error, try `rustc --explain E0252`.
|
|
@ -1,17 +1,16 @@
|
||||||
error[E0259]: the name `derive_a` is defined multiple times
|
error[E0259]: the name `derive_a` is defined multiple times
|
||||||
--> $DIR/shadow.rs:6:1
|
--> $DIR/shadow.rs:6:1
|
||||||
|
|
|
|
||||||
LL | extern crate derive_a;
|
LL | extern crate derive_a;
|
||||||
| ---------------------- previous import of the extern crate `derive_a` here
|
| ---------------------- previous import of the extern crate `derive_a` here
|
||||||
LL | #[macro_use]
|
LL | / #[macro_use]
|
||||||
LL | extern crate derive_a; //~ ERROR the name `derive_a` is defined multiple times
|
LL | | extern crate derive_a; //~ ERROR the name `derive_a` is defined multiple times
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ `derive_a` reimported here
|
| | ^^^^^^^^^^^^^^^^^^^^^-
|
||||||
|
| |_|____________________|
|
||||||
|
| | help: remove unnecessary import
|
||||||
|
| `derive_a` reimported here
|
||||||
|
|
|
|
||||||
= note: `derive_a` must be defined only once in the type namespace of this module
|
= note: `derive_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 derive_a as other_derive_a; //~ ERROR the name `derive_a` is defined multiple times
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,12 @@ error[E0252]: the name `transmute` is defined multiple times
|
||||||
LL | use std::mem::transmute;
|
LL | use std::mem::transmute;
|
||||||
| ------------------- previous import of the value `transmute` here
|
| ------------------- previous import of the value `transmute` here
|
||||||
LL | use std::mem::transmute;
|
LL | use std::mem::transmute;
|
||||||
| ^^^^^^^^^^^^^^^^^^^ `transmute` reimported here
|
| ----^^^^^^^^^^^^^^^^^^^-
|
||||||
|
| | |
|
||||||
|
| | `transmute` reimported here
|
||||||
|
| help: remove unnecessary import
|
||||||
|
|
|
|
||||||
= note: `transmute` must be defined only once in the value namespace of this module
|
= note: `transmute` must be defined only once in the value namespace of this module
|
||||||
help: you can use `as` to change the binding name of the import
|
|
||||||
|
|
|
||||||
LL | use std::mem::transmute as other_transmute;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,12 @@ error[E0254]: the name `core` is defined multiple times
|
||||||
LL | extern crate core;
|
LL | extern crate core;
|
||||||
| ------------------ previous import of the extern crate `core` here
|
| ------------------ previous import of the extern crate `core` here
|
||||||
LL | use core;
|
LL | use core;
|
||||||
| ^^^^ `core` reimported here
|
| ----^^^^-
|
||||||
|
| | |
|
||||||
|
| | `core` reimported here
|
||||||
|
| help: remove unnecessary import
|
||||||
|
|
|
|
||||||
= note: `core` must be defined only once in the type namespace of this module
|
= note: `core` 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 core as other_core;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -20,13 +20,12 @@ LL | self,
|
||||||
| ---- previous import of the module `bar` here
|
| ---- previous import of the module `bar` here
|
||||||
...
|
...
|
||||||
LL | self
|
LL | self
|
||||||
| ^^^^ `bar` reimported here
|
| ^^^^
|
||||||
|
| |
|
||||||
|
| `bar` reimported here
|
||||||
|
| help: remove unnecessary import
|
||||||
|
|
|
|
||||||
= note: `bar` must be defined only once in the type namespace of this module
|
= note: `bar` 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 | self as other_bar
|
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,12 @@ error[E0252]: the name `mem` is defined multiple times
|
||||||
LL | use std::{mem, ptr};
|
LL | use std::{mem, ptr};
|
||||||
| --- previous import of the module `mem` here
|
| --- previous import of the module `mem` here
|
||||||
LL | use std::mem; //~ ERROR the name `mem` is defined multiple times
|
LL | use std::mem; //~ ERROR the name `mem` is defined multiple times
|
||||||
| ^^^^^^^^ `mem` reimported here
|
| ----^^^^^^^^-
|
||||||
|
| | |
|
||||||
|
| | `mem` reimported here
|
||||||
|
| help: remove unnecessary import
|
||||||
|
|
|
|
||||||
= note: `mem` must be defined only once in the type namespace of this module
|
= note: `mem` 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 std::mem as other_mem; //~ ERROR the name `mem` is defined multiple times
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue