Skip to content

Commit 0cf7d5d

Browse files
committed
Merge branch 'rfc_1560_warning_cycle' of https://github.com/jseyfried/rust into rollup
Conflicts: src/librustc_resolve/lib.rs src/librustc_resolve/resolve_imports.rs
2 parents 5f1ecb0 + cfabce2 commit 0cf7d5d

File tree

6 files changed

+111
-28
lines changed

6 files changed

+111
-28
lines changed

src/librustc/lint/builtin.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,12 @@ declare_lint! {
211211
not named `mod.rs`"
212212
}
213213

214+
declare_lint! {
215+
pub LEGACY_IMPORTS,
216+
Warn,
217+
"detects names that resolve to ambiguous glob imports with RFC 1560"
218+
}
219+
214220
declare_lint! {
215221
pub DEPRECATED,
216222
Warn,
@@ -257,6 +263,7 @@ impl LintPass for HardwiredLints {
257263
PATTERNS_IN_FNS_WITHOUT_BODY,
258264
EXTRA_REQUIREMENT_IN_IMPL,
259265
LEGACY_DIRECTORY_OWNERSHIP,
266+
LEGACY_IMPORTS,
260267
DEPRECATED
261268
)
262269
}

src/librustc_lint/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
234234
id: LintId::of(LEGACY_DIRECTORY_OWNERSHIP),
235235
reference: "issue #37872 <https://github.com/rust-lang/rust/issues/37872>",
236236
},
237+
FutureIncompatibleInfo {
238+
id: LintId::of(LEGACY_IMPORTS),
239+
reference: "issue #38260 <https://github.com/rust-lang/rust/issues/38260>",
240+
},
237241
]);
238242

239243
// Register renamed and removed lints

src/librustc_resolve/lib.rs

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
6464
use syntax::ast::{Local, Mutability, Pat, PatKind, Path};
6565
use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind};
6666

67-
use syntax_pos::{Span, DUMMY_SP};
67+
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
6868
use errors::DiagnosticBuilder;
6969

7070
use std::cell::{Cell, RefCell};
@@ -896,6 +896,7 @@ enum NameBindingKind<'a> {
896896
Ambiguity {
897897
b1: &'a NameBinding<'a>,
898898
b2: &'a NameBinding<'a>,
899+
legacy: bool,
899900
}
900901
}
901902

@@ -907,13 +908,15 @@ struct AmbiguityError<'a> {
907908
lexical: bool,
908909
b1: &'a NameBinding<'a>,
909910
b2: &'a NameBinding<'a>,
911+
legacy: bool,
910912
}
911913

912914
impl<'a> NameBinding<'a> {
913915
fn module(&self) -> Option<Module<'a>> {
914916
match self.kind {
915917
NameBindingKind::Module(module) => Some(module),
916918
NameBindingKind::Import { binding, .. } => binding.module(),
919+
NameBindingKind::Ambiguity { legacy: true, b1, .. } => b1.module(),
917920
_ => None,
918921
}
919922
}
@@ -923,6 +926,7 @@ impl<'a> NameBinding<'a> {
923926
NameBindingKind::Def(def) => def,
924927
NameBindingKind::Module(module) => module.def().unwrap(),
925928
NameBindingKind::Import { binding, .. } => binding.def(),
929+
NameBindingKind::Ambiguity { legacy: true, b1, .. } => b1.def(),
926930
NameBindingKind::Ambiguity { .. } => Def::Err,
927931
}
928932
}
@@ -1349,11 +1353,14 @@ impl<'a> Resolver<'a> {
13491353
self.record_use(ident, ns, binding, span)
13501354
}
13511355
NameBindingKind::Import { .. } => false,
1352-
NameBindingKind::Ambiguity { b1, b2 } => {
1356+
NameBindingKind::Ambiguity { b1, b2, legacy } => {
13531357
self.ambiguity_errors.push(AmbiguityError {
1354-
span: span, name: ident.name, lexical: false, b1: b1, b2: b2,
1358+
span: span, name: ident.name, lexical: false, b1: b1, b2: b2, legacy: legacy,
13551359
});
1356-
true
1360+
if legacy {
1361+
self.record_use(name, ns, b1, span);
1362+
}
1363+
!legacy
13571364
}
13581365
_ => false
13591366
}
@@ -3046,26 +3053,39 @@ impl<'a> Resolver<'a> {
30463053
self.report_shadowing_errors();
30473054
let mut reported_spans = FxHashSet();
30483055

3049-
for &AmbiguityError { span, name, b1, b2, lexical } in &self.ambiguity_errors {
3056+
for &AmbiguityError { span, name, b1, b2, lexical, legacy } in &self.ambiguity_errors {
30503057
if !reported_spans.insert(span) { continue }
30513058
let participle = |binding: &NameBinding| {
30523059
if binding.is_import() { "imported" } else { "defined" }
30533060
};
30543061
let msg1 = format!("`{}` could resolve to the name {} here", name, participle(b1));
30553062
let msg2 = format!("`{}` could also resolve to the name {} here", name, participle(b2));
3056-
self.session.struct_span_err(span, &format!("`{}` is ambiguous", name))
3057-
.span_note(b1.span, &msg1)
3058-
.span_note(b2.span, &msg2)
3059-
.note(&if !lexical && b1.is_glob_import() {
3060-
format!("consider adding an explicit import of `{}` to disambiguate", name)
3061-
} else if let Def::Macro(..) = b1.def() {
3062-
format!("macro-expanded {} do not shadow",
3063-
if b1.is_import() { "macro imports" } else { "macros" })
3064-
} else {
3065-
format!("macro-expanded {} do not shadow when used in a macro invocation path",
3066-
if b1.is_import() { "imports" } else { "items" })
3067-
})
3068-
.emit();
3063+
let note = if !lexical && b1.is_glob_import() {
3064+
format!("consider adding an explicit import of `{}` to disambiguate", name)
3065+
} else if let Def::Macro(..) = b1.def() {
3066+
format!("macro-expanded {} do not shadow",
3067+
if b1.is_import() { "macro imports" } else { "macros" })
3068+
} else {
3069+
format!("macro-expanded {} do not shadow when used in a macro invocation path",
3070+
if b1.is_import() { "imports" } else { "items" })
3071+
};
3072+
if legacy {
3073+
let id = match b2.kind {
3074+
NameBindingKind::Import { directive, .. } => directive.id,
3075+
_ => unreachable!(),
3076+
};
3077+
let mut span = MultiSpan::from_span(span);
3078+
span.push_span_label(b1.span, msg1);
3079+
span.push_span_label(b2.span, msg2);
3080+
let msg = format!("`{}` is ambiguous", name);
3081+
self.session.add_lint(lint::builtin::LEGACY_IMPORTS, id, span, msg);
3082+
} else {
3083+
self.session.struct_span_err(span, &format!("`{}` is ambiguous", name))
3084+
.span_note(b1.span, &msg1)
3085+
.span_note(b2.span, &msg2)
3086+
.note(&note)
3087+
.emit();
3088+
}
30693089
}
30703090

30713091
for &PrivacyError(span, name, binding) in &self.privacy_errors {

src/librustc_resolve/macros.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ impl<'a> Resolver<'a> {
265265
let name = ident.name;
266266
self.ambiguity_errors.push(AmbiguityError {
267267
span: span, name: name, b1: shadower, b2: binding, lexical: true,
268+
legacy: false,
268269
});
269270
return Ok(shadower);
270271
}

src/librustc_resolve/resolve_imports.rs

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ impl<'a> Resolver<'a> {
160160
binding.def() != shadowed_glob.def() {
161161
self.ambiguity_errors.push(AmbiguityError {
162162
span: span, name: name, lexical: false, b1: binding, b2: shadowed_glob,
163+
legacy: false,
163164
});
164165
}
165166
}
@@ -339,9 +340,9 @@ impl<'a> Resolver<'a> {
339340
}
340341

341342
pub fn ambiguity(&mut self, b1: &'a NameBinding<'a>, b2: &'a NameBinding<'a>)
342-
-> &'a NameBinding<'a> {
343+
-> &'a NameBinding<'a> {
343344
self.arenas.alloc_name_binding(NameBinding {
344-
kind: NameBindingKind::Ambiguity { b1: b1, b2: b2 },
345+
kind: NameBindingKind::Ambiguity { b1: b1, b2: b2, legacy: false },
345346
vis: if b1.vis.is_at_least(b2.vis, self) { b1.vis } else { b2.vis },
346347
span: b1.span,
347348
expansion: Mark::root(),
@@ -728,7 +729,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
728729
}
729730

730731
for (&(ident, ns), resolution) in module.resolutions.borrow().iter() {
731-
let resolution = resolution.borrow();
732+
let resolution = &mut *resolution.borrow_mut();
732733
let binding = match resolution.binding {
733734
Some(binding) => binding,
734735
None => continue,
@@ -745,14 +746,34 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
745746
}
746747
}
747748

748-
if let NameBindingKind::Import { binding: orig_binding, directive, .. } = binding.kind {
749-
if ns == TypeNS && orig_binding.is_variant() &&
750-
!orig_binding.vis.is_at_least(binding.vis, self) {
751-
let msg = format!("variant `{}` is private, and cannot be reexported \
752-
(error E0364), consider declaring its enum as `pub`",
753-
ident);
754-
self.session.add_lint(PRIVATE_IN_PUBLIC, directive.id, binding.span, msg);
749+
match binding.kind {
750+
NameBindingKind::Import { binding: orig_binding, directive, .. } => {
751+
if ns == TypeNS && orig_binding.is_variant() &&
752+
!orig_binding.vis.is_at_least(binding.vis, self) {
753+
let msg = format!("variant `{}` is private, and cannot be reexported \
754+
(error E0364), consider declaring its enum as `pub`",
755+
ident);
756+
self.session.add_lint(PRIVATE_IN_PUBLIC, directive.id, binding.span, msg);
757+
}
758+
}
759+
NameBindingKind::Ambiguity { b1, b2, .. }
760+
if b1.is_glob_import() && b2.is_glob_import() => {
761+
let (orig_b1, orig_b2) = match (&b1.kind, &b2.kind) {
762+
(&NameBindingKind::Import { binding: b1, .. },
763+
&NameBindingKind::Import { binding: b2, .. }) => (b1, b2),
764+
_ => continue,
765+
};
766+
let (b1, b2) = match (orig_b1.vis, orig_b2.vis) {
767+
(ty::Visibility::Public, ty::Visibility::Public) => continue,
768+
(ty::Visibility::Public, _) => (b1, b2),
769+
(_, ty::Visibility::Public) => (b2, b1),
770+
_ => continue,
771+
};
772+
resolution.binding = Some(self.arenas.alloc_name_binding(NameBinding {
773+
kind: NameBindingKind::Ambiguity { b1: b1, b2: b2, legacy: true }, ..*b1
774+
}));
755775
}
776+
_ => {}
756777
}
757778
}
758779

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2016 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+
#![feature(rustc_attrs)]
12+
#![allow(unused)]
13+
14+
pub struct Foo;
15+
16+
mod bar {
17+
struct Foo;
18+
19+
mod baz {
20+
use *; //~ NOTE `Foo` could resolve to the name imported here
21+
use bar::*; //~ NOTE `Foo` could also resolve to the name imported here
22+
fn f(_: Foo) {}
23+
//~^ WARN `Foo` is ambiguous
24+
//~| WARN hard error in a future release
25+
//~| NOTE see issue #38260
26+
}
27+
}
28+
29+
#[rustc_error]
30+
fn main() {} //~ ERROR compilation successful

0 commit comments

Comments
 (0)