diff options
| author | bors <bors@rust-lang.org> | 2016-01-11 06:40:58 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-01-11 06:40:58 +0000 |
| commit | 69e1f57dfbd32a1a342d696a3e79624da97ebe1b (patch) | |
| tree | 42571100253fd85695b9a256399e9476c2974253 | |
| parent | d70ab2bdf16c22b9f3ff0230089b44855e3f1593 (diff) | |
| parent | 834fb17e9476204dbd5723cd2cc3617bf848b9e9 (diff) | |
| download | rust-69e1f57dfbd32a1a342d696a3e79624da97ebe1b.tar.gz rust-69e1f57dfbd32a1a342d696a3e79624da97ebe1b.zip | |
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.
| -rw-r--r-- | src/librustc_resolve/build_reduced_graph.rs | 2 | ||||
| -rw-r--r-- | src/librustc_resolve/lib.rs | 33 |
2 files changed, 22 insertions, 13 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 1d3f2b79844..8ed47300a17 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -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()); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index a5a22fd7f39..c7031f72af4 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -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)); } } |
