From d4a78da543fd8959edf386602537bece057a3918 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 31 Oct 2018 00:22:19 +0300 Subject: [PATCH 1/3] resolve: Prohibit relative paths in visibilities on 2018 edition --- src/librustc_resolve/lib.rs | 13 ++++++++++++- src/test/ui/privacy/restricted/relative-2018.rs | 13 +++++++++++++ .../ui/privacy/restricted/relative-2018.stderr | 16 ++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/privacy/restricted/relative-2018.rs create mode 100644 src/test/ui/privacy/restricted/relative-2018.stderr diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 12dabd2a31da1..a392ab717c06c 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -4710,7 +4710,18 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ty::Visibility::Restricted(self.current_module.normal_ancestor_id) } ast::VisibilityKind::Restricted { ref path, id, .. } => { - // Visibilities are resolved as global by default, add starting root segment. + // For visibilities we are not ready to provide correct implementation of "uniform + // paths" right now, so on 2018 edition we only allow module-relative paths for now. + let first_ident = path.segments[0].ident; + if self.session.rust_2018() && !first_ident.is_path_segment_keyword() { + let msg = "relative paths are not supported in visibilities on 2018 edition"; + self.session.struct_span_err(first_ident.span, msg) + .span_suggestion(path.span, "try", format!("crate::{}", path)) + .emit(); + return ty::Visibility::Public; + } + // On 2015 visibilities are resolved as crate-relative by default, + // add starting root segment if necessary. let segments = path.make_root().iter().chain(path.segments.iter()) .map(|seg| Segment { ident: seg.ident, id: Some(seg.id) }) .collect::>(); diff --git a/src/test/ui/privacy/restricted/relative-2018.rs b/src/test/ui/privacy/restricted/relative-2018.rs new file mode 100644 index 0000000000000..69b7c1e4d4f3c --- /dev/null +++ b/src/test/ui/privacy/restricted/relative-2018.rs @@ -0,0 +1,13 @@ +// edition:2018 + +mod m { + pub(in crate) struct S1; // OK + pub(in super) struct S2; // OK + pub(in self) struct S3; // OK + pub(in ::core) struct S4; + //~^ ERROR visibilities can only be restricted to ancestor modules + pub(in a::b) struct S5; + //~^ ERROR relative paths are not supported in visibilities on 2018 edition +} + +fn main() {} diff --git a/src/test/ui/privacy/restricted/relative-2018.stderr b/src/test/ui/privacy/restricted/relative-2018.stderr new file mode 100644 index 0000000000000..61effc463e98f --- /dev/null +++ b/src/test/ui/privacy/restricted/relative-2018.stderr @@ -0,0 +1,16 @@ +error: visibilities can only be restricted to ancestor modules + --> $DIR/relative-2018.rs:7:12 + | +LL | pub(in ::core) struct S4; + | ^^^^^^ + +error: relative paths are not supported in visibilities on 2018 edition + --> $DIR/relative-2018.rs:9:12 + | +LL | pub(in a::b) struct S5; + | ^--- + | | + | help: try: `crate::a::b` + +error: aborting due to 2 previous errors + From e593431bc7f3ad89aea8e792384d6719bf60f3f3 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 25 Nov 2018 04:25:59 +0300 Subject: [PATCH 2/3] resolve: Fix bad span arithmetics in import conflict diagnostics --- src/librustc_resolve/lib.rs | 10 +++++----- src/test/ui/issues/issue-45829/import-self.rs | 3 +++ .../ui/issues/issue-45829/import-self.stderr | 20 ++++++++++++++++--- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index a392ab717c06c..443b1ccdef836 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -4999,10 +4999,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { err.span_suggestion_with_applicability( binding.span, &rename_msg, - match (&directive.subclass, snippet.as_ref()) { - (ImportDirectiveSubclass::SingleImport { .. }, "self") => + match directive.subclass { + ImportDirectiveSubclass::SingleImport { type_ns_only: true, .. } => format!("self as {}", suggested_name), - (ImportDirectiveSubclass::SingleImport { source, .. }, _) => + ImportDirectiveSubclass::SingleImport { source, .. } => format!( "{} as {}{}", &snippet[..((source.span.hi().0 - binding.span.lo().0) as usize)], @@ -5013,13 +5013,13 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { "" } ), - (ImportDirectiveSubclass::ExternCrate { source, target, .. }, _) => + ImportDirectiveSubclass::ExternCrate { source, target, .. } => format!( "extern crate {} as {};", source.unwrap_or(target.name), suggested_name, ), - (_, _) => unreachable!(), + _ => unreachable!(), }, Applicability::MaybeIncorrect, ); diff --git a/src/test/ui/issues/issue-45829/import-self.rs b/src/test/ui/issues/issue-45829/import-self.rs index 8b13ffd0076d5..eb5fb458d8279 100644 --- a/src/test/ui/issues/issue-45829/import-self.rs +++ b/src/test/ui/issues/issue-45829/import-self.rs @@ -19,4 +19,7 @@ use foo as self; use foo::self; +use foo::A; +use foo::{self as A}; + fn main() {} diff --git a/src/test/ui/issues/issue-45829/import-self.stderr b/src/test/ui/issues/issue-45829/import-self.stderr index 985dc4e7131cf..55e51952a8804 100644 --- a/src/test/ui/issues/issue-45829/import-self.stderr +++ b/src/test/ui/issues/issue-45829/import-self.stderr @@ -25,7 +25,21 @@ 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 +error[E0252]: the name `A` is defined multiple times + --> $DIR/import-self.rs:23:11 + | +LL | use foo::A; + | ------ previous import of the type `A` here +LL | use foo::{self as A}; + | ^^^^^^^^^ `A` reimported 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::{self as OtherA}; + | ^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors -Some errors occurred: E0255, E0429. -For more information about an error, try `rustc --explain E0255`. +Some errors occurred: E0252, E0255, E0429. +For more information about an error, try `rustc --explain E0252`. From fe548e311a8f3a2e193989dc959841874738423f Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 25 Nov 2018 05:45:43 +0300 Subject: [PATCH 3/3] resolve: Fix some more asserts in import validation --- src/librustc_resolve/resolve_imports.rs | 3 +- src/test/ui/imports/auxiliary/issue-56125.rs | 2 + src/test/ui/imports/issue-56125.rs | 25 +++++++-- src/test/ui/imports/issue-56125.stderr | 59 +++++++++++++------- 4 files changed, 63 insertions(+), 26 deletions(-) diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 616cc9d2fc51b..52e3e54b9f931 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -864,7 +864,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } PathResult::NonModule(path_res) if path_res.base_def() == Def::Err => { // The error was already reported earlier. - assert!(directive.imported_module.get().is_none()); + assert!(!self.ambiguity_errors.is_empty() || + directive.imported_module.get().is_none()); return None; } PathResult::Indeterminate | PathResult::NonModule(..) => unreachable!(), diff --git a/src/test/ui/imports/auxiliary/issue-56125.rs b/src/test/ui/imports/auxiliary/issue-56125.rs index 0ff407756b3ae..8e0797582970d 100644 --- a/src/test/ui/imports/auxiliary/issue-56125.rs +++ b/src/test/ui/imports/auxiliary/issue-56125.rs @@ -1,3 +1,5 @@ +pub mod issue_56125 {} + pub mod last_segment { pub mod issue_56125 {} } diff --git a/src/test/ui/imports/issue-56125.rs b/src/test/ui/imports/issue-56125.rs index 4baeb8a34dd76..843b52f18435e 100644 --- a/src/test/ui/imports/issue-56125.rs +++ b/src/test/ui/imports/issue-56125.rs @@ -2,11 +2,24 @@ // compile-flags:--extern issue_56125 // aux-build:issue-56125.rs -use issue_56125::last_segment::*; -//~^ ERROR `issue_56125` is ambiguous -//~| ERROR unresolved import `issue_56125::last_segment` -use issue_56125::non_last_segment::non_last_segment::*; -//~^ ERROR `issue_56125` is ambiguous -//~| ERROR failed to resolve: could not find `non_last_segment` in `issue_56125` +#![feature(uniform_paths)] + +mod m1 { + use issue_56125::last_segment::*; + //~^ ERROR `issue_56125` is ambiguous + //~| ERROR unresolved import `issue_56125::last_segment` +} + +mod m2 { + use issue_56125::non_last_segment::non_last_segment::*; + //~^ ERROR `issue_56125` is ambiguous + //~| ERROR failed to resolve: could not find `non_last_segment` in `issue_56125` +} + +mod m3 { + mod empty {} + use empty::issue_56125; //~ ERROR unresolved import `empty::issue_56125` + use issue_56125::*; //~ ERROR `issue_56125` is ambiguous +} fn main() {} diff --git a/src/test/ui/imports/issue-56125.stderr b/src/test/ui/imports/issue-56125.stderr index 096d5be97f0e0..b1292ef8f783e 100644 --- a/src/test/ui/imports/issue-56125.stderr +++ b/src/test/ui/imports/issue-56125.stderr @@ -1,46 +1,67 @@ error[E0433]: failed to resolve: could not find `non_last_segment` in `issue_56125` - --> $DIR/issue-56125.rs:8:18 + --> $DIR/issue-56125.rs:14:22 | -LL | use issue_56125::non_last_segment::non_last_segment::*; - | ^^^^^^^^^^^^^^^^ could not find `non_last_segment` in `issue_56125` +LL | use issue_56125::non_last_segment::non_last_segment::*; + | ^^^^^^^^^^^^^^^^ could not find `non_last_segment` in `issue_56125` error[E0432]: unresolved import `issue_56125::last_segment` - --> $DIR/issue-56125.rs:5:18 + --> $DIR/issue-56125.rs:8:22 | -LL | use issue_56125::last_segment::*; - | ^^^^^^^^^^^^ could not find `last_segment` in `issue_56125` +LL | use issue_56125::last_segment::*; + | ^^^^^^^^^^^^ could not find `last_segment` in `issue_56125` + +error[E0432]: unresolved import `empty::issue_56125` + --> $DIR/issue-56125.rs:21:9 + | +LL | use empty::issue_56125; //~ ERROR unresolved import `empty::issue_56125` + | ^^^^^^^^^^^^^^^^^^ no `issue_56125` in `m3::empty` error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution) - --> $DIR/issue-56125.rs:5:5 + --> $DIR/issue-56125.rs:8:9 | -LL | use issue_56125::last_segment::*; - | ^^^^^^^^^^^ ambiguous name +LL | use issue_56125::last_segment::*; + | ^^^^^^^^^^^ ambiguous name | = note: `issue_56125` could refer to an extern crate passed with `--extern` = help: use `::issue_56125` to refer to this extern crate unambiguously note: `issue_56125` could also refer to the module imported here - --> $DIR/issue-56125.rs:5:5 + --> $DIR/issue-56125.rs:8:9 | -LL | use issue_56125::last_segment::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | use issue_56125::last_segment::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: use `self::issue_56125` to refer to this module unambiguously error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution) - --> $DIR/issue-56125.rs:8:5 + --> $DIR/issue-56125.rs:14:9 | -LL | use issue_56125::non_last_segment::non_last_segment::*; - | ^^^^^^^^^^^ ambiguous name +LL | use issue_56125::non_last_segment::non_last_segment::*; + | ^^^^^^^^^^^ ambiguous name | = note: `issue_56125` could refer to an extern crate passed with `--extern` = help: use `::issue_56125` to refer to this extern crate unambiguously note: `issue_56125` could also refer to the module imported here - --> $DIR/issue-56125.rs:5:5 + --> $DIR/issue-56125.rs:14:9 | -LL | use issue_56125::last_segment::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | use issue_56125::non_last_segment::non_last_segment::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: use `self::issue_56125` to refer to this module unambiguously -error: aborting due to 4 previous errors +error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution) + --> $DIR/issue-56125.rs:22:9 + | +LL | use issue_56125::*; //~ ERROR `issue_56125` is ambiguous + | ^^^^^^^^^^^ ambiguous name + | + = note: `issue_56125` could refer to an extern crate passed with `--extern` + = help: use `::issue_56125` to refer to this extern crate unambiguously +note: `issue_56125` could also refer to the unresolved item imported here + --> $DIR/issue-56125.rs:21:9 + | +LL | use empty::issue_56125; //~ ERROR unresolved import `empty::issue_56125` + | ^^^^^^^^^^^^^^^^^^ + = help: use `self::issue_56125` to refer to this unresolved item unambiguously + +error: aborting due to 6 previous errors Some errors occurred: E0432, E0433, E0659. For more information about an error, try `rustc --explain E0432`.