Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add ABSOLUTE_PATH_STARTING_WITH_MODULE epoch lint for path breakage
  • Loading branch information
Manishearth committed Apr 20, 2018
commit 37d3bea3ec3d47dbf1f7352c32fab75ce408798c
8 changes: 8 additions & 0 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,13 @@ declare_lint! {
"suggest using `dyn Trait` for trait objects"
}

declare_lint! {
pub ABSOLUTE_PATH_STARTING_WITH_MODULE,
Allow,
"fully qualified paths that start with a module name \
instead of `crate`, `self`, or an extern crate name"
}

declare_lint! {
pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
Warn,
Expand Down Expand Up @@ -314,6 +321,7 @@ impl LintPass for HardwiredLints {
TYVAR_BEHIND_RAW_POINTER,
ELIDED_LIFETIME_IN_PATH,
BARE_TRAIT_OBJECT,
ABSOLUTE_PATH_STARTING_WITH_MODULE,
UNSTABLE_NAME_COLLISION,
)
}
Expand Down
7 changes: 6 additions & 1 deletion src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ extern crate rustc_mir;
extern crate syntax_pos;

use rustc::lint;
use rustc::lint::builtin::BARE_TRAIT_OBJECT;
use rustc::lint::builtin::{BARE_TRAIT_OBJECT, ABSOLUTE_PATH_STARTING_WITH_MODULE};
use rustc::session;
use rustc::util;

Expand Down Expand Up @@ -278,6 +278,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
// Note: this item represents future incompatibility of all unstable functions in the
// standard library, and thus should never be removed or changed to an error.
},
FutureIncompatibleInfo {
id: LintId::of(ABSOLUTE_PATH_STARTING_WITH_MODULE),
reference: "issue TBD",
edition: Some(Edition::Edition2018),
},
]);

// Register renamed and removed lints
Expand Down
29 changes: 27 additions & 2 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3189,7 +3189,7 @@ impl<'a> Resolver<'a> {
path[0].name != keywords::CrateRoot.name() &&
path[0].name != keywords::DollarCrate.name() {
let unqualified_result = {
match self.resolve_path(&[*path.last().unwrap()], Some(ns), false, span, Some(id)) {
match self.resolve_path(&[*path.last().unwrap()], Some(ns), false, span, None) {
PathResult::NonModule(path_res) => path_res.base_def(),
PathResult::Module(module) => module.def().unwrap(),
_ => return Some(result),
Expand All @@ -3209,7 +3209,8 @@ impl<'a> Resolver<'a> {
opt_ns: Option<Namespace>, // `None` indicates a module path
record_used: bool,
path_span: Span,
_node_id: Option<NodeId>)
node_id: Option<NodeId>) // None indicates that we don't care about linting
// `::module` paths
-> PathResult<'a> {
let mut module = None;
let mut allow_super = true;
Expand Down Expand Up @@ -3328,6 +3329,30 @@ impl<'a> Resolver<'a> {
format!("Not a module `{}`", ident),
is_last);
}

if let Some(id) = node_id {
if i == 1 && self.session.features_untracked().crate_in_paths
&& !self.session.rust_2018() {
let prev_name = path[0].name;
if prev_name == keywords::Extern.name() ||
prev_name == keywords::CrateRoot.name() {
let mut is_crate = false;
if let NameBindingKind::Import { directive: d, .. } = binding.kind {
if let ImportDirectiveSubclass::ExternCrate(..) = d.subclass {
is_crate = true;
}
}

if !is_crate {
self.session.buffer_lint(
lint::builtin::ABSOLUTE_PATH_STARTING_WITH_MODULE,
id, path_span,
"Fully-qualified paths must start with `self`, `super`,
`crate`, or an external crate name in the 2018 edition");
}
}
}
}
}
Err(Undetermined) => return PathResult::Indeterminate,
Err(Determined) => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_resolve/resolve_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
!(self_path.len() > 1 && is_special(self_path[1])) {
self_path[0].name = keywords::SelfValue.name();
self_result = Some(self.resolve_path(&self_path, None, false,
span, Some(directive.id)));
span, None));
}
return if let Some(PathResult::Module(..)) = self_result {
Some((span, format!("Did you mean `{}`?", names_to_string(&self_path[..]))))
Expand Down