Auto merge of #30295 - jseyfried:fix_extern_crate_duplicate, r=nrc
Fix a bug allowing an item and an external crate to collide so long as the external crate is declared after the item. For example, ```rust mod core { pub fn f() {} } // This would be an error if it followed the `extern crate` extern crate core; // This declaration is shadowed by the preceding module fn main() { core::f(); } ``` This is a [breaking-change], but it looks unlikely to cause breakage in practice, and any breakage can be fixed by removing colliding `extern crate` declarations, which are shadowed and hence unused.
This commit is contained in:
commit
69e1f57dfb
@ -325,7 +325,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||
|
||||
debug!("(build reduced graph for item) found extern `{}`",
|
||||
module_to_string(&*external_module));
|
||||
self.check_for_conflicts_between_external_crates(&**parent, name, sp);
|
||||
self.check_for_conflicts_for_external_crate(&parent, name, sp);
|
||||
parent.external_module_children
|
||||
.borrow_mut()
|
||||
.insert(name, external_module.clone());
|
||||
|
@ -122,6 +122,8 @@ enum SuggestionType {
|
||||
}
|
||||
|
||||
pub enum ResolutionError<'a> {
|
||||
/// error E0260: name conflicts with an extern crate
|
||||
NameConflictsWithExternCrate(Name),
|
||||
/// error E0401: can't use type parameters from outer function
|
||||
TypeParametersFromOuterFunction,
|
||||
/// error E0402: cannot use an outer type parameter in this context
|
||||
@ -228,6 +230,14 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
|
||||
}
|
||||
|
||||
match resolution_error {
|
||||
ResolutionError::NameConflictsWithExternCrate(name) => {
|
||||
struct_span_err!(resolver.session,
|
||||
span,
|
||||
E0260,
|
||||
"the name `{}` conflicts with an external crate \
|
||||
that has been imported into this module",
|
||||
name)
|
||||
}
|
||||
ResolutionError::TypeParametersFromOuterFunction => {
|
||||
struct_span_err!(resolver.session,
|
||||
span,
|
||||
@ -1297,12 +1307,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks that the names of external crates don't collide with other
|
||||
/// external crates.
|
||||
fn check_for_conflicts_between_external_crates(&self,
|
||||
module: &Module,
|
||||
name: Name,
|
||||
span: Span) {
|
||||
/// Check that an external crate doesn't collide with items or other external crates.
|
||||
fn check_for_conflicts_for_external_crate(&self, module: &Module, name: Name, span: Span) {
|
||||
if module.external_module_children.borrow().contains_key(&name) {
|
||||
span_err!(self.session,
|
||||
span,
|
||||
@ -1310,6 +1316,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
"an external crate named `{}` has already been imported into this module",
|
||||
name);
|
||||
}
|
||||
match module.children.borrow().get(&name) {
|
||||
Some(name_bindings) if name_bindings.type_ns.defined() => {
|
||||
resolve_error(self,
|
||||
name_bindings.type_ns.span().unwrap_or(codemap::DUMMY_SP),
|
||||
ResolutionError::NameConflictsWithExternCrate(name));
|
||||
}
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks that the names of items don't collide with external crates.
|
||||
@ -1318,12 +1332,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
name: Name,
|
||||
span: Span) {
|
||||
if module.external_module_children.borrow().contains_key(&name) {
|
||||
span_err!(self.session,
|
||||
span,
|
||||
E0260,
|
||||
"the name `{}` conflicts with an external crate that has been imported \
|
||||
into this module",
|
||||
name);
|
||||
resolve_error(self, span, ResolutionError::NameConflictsWithExternCrate(name));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user