Skip to content

Commit

Permalink
Add lint for crates used through modules
Browse files Browse the repository at this point in the history
  • Loading branch information
Manishearth committed Apr 27, 2018
1 parent 78fd719 commit c904d98
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
8 changes: 8 additions & 0 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,13 @@ declare_lint! {
"detects name collision with an existing but unstable method"
}


declare_lint! {
pub USE_CRATE_IN_MODULE,
Allow,
"attempting to use a crate through another module"
}

/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
Expand Down Expand Up @@ -323,6 +330,7 @@ impl LintPass for HardwiredLints {
BARE_TRAIT_OBJECT,
ABSOLUTE_PATH_STARTING_WITH_MODULE,
UNSTABLE_NAME_COLLISION,
USE_CRATE_IN_MODULE
)
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ extern crate syntax_pos;

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

Expand Down Expand Up @@ -182,7 +183,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
"rust_2018_idioms",
BARE_TRAIT_OBJECT,
UNREACHABLE_PUB,
UNNECESSARY_EXTERN_CRATE);
UNNECESSARY_EXTERN_CRATE,
USE_CRATE_IN_MODULE);

// Guidelines for creating a future incompatibility lint:
//
Expand Down
30 changes: 30 additions & 0 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3233,6 +3233,10 @@ impl<'a> Resolver<'a> {
let mut module = None;
let mut allow_super = true;

let mut fully_local = true;
// are we doing the first resolution? I.e. ignoring :: and crate
// and stuff, have we resolved anything yet?
let mut first_resolution = true;
for (i, &ident) in path.iter().enumerate() {
debug!("resolve_path ident {} {:?}", i, ident);
let is_last = i == path.len() - 1;
Expand All @@ -3242,8 +3246,10 @@ impl<'a> Resolver<'a> {
if i == 0 && ns == TypeNS && name == keywords::SelfValue.name() {
let mut ctxt = ident.span.ctxt().modern();
module = Some(self.resolve_self(&mut ctxt, self.current_module));
first_resolution = false;
continue
} else if allow_super && ns == TypeNS && name == keywords::Super.name() {
first_resolution = false;
let mut ctxt = ident.span.ctxt().modern();
let self_module = match i {
0 => self.resolve_self(&mut ctxt, self.current_module),
Expand All @@ -3270,6 +3276,7 @@ impl<'a> Resolver<'a> {
continue
} else if i == 0 && name == keywords::DollarCrate.name() {
// `$crate::a::b`
fully_local = false;
module = Some(self.resolve_crate_root(ident.span.ctxt(), true));
continue
} else if i == 1 && !token::is_path_segment_keyword(ident) {
Expand All @@ -3285,6 +3292,8 @@ impl<'a> Resolver<'a> {
self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
self.populate_module_if_necessary(crate_root);
module = Some(crate_root);
fully_local = false;
first_resolution = false;
continue
}
}
Expand Down Expand Up @@ -3337,6 +3346,27 @@ impl<'a> Resolver<'a> {
let def = binding.def();
let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(def);
if let Some(next_module) = binding.module() {
if ns == TypeNS && fully_local && module.is_some() && !first_resolution {
if let Some(id) = node_id {
if self.extern_prelude.contains(&ident.name) {
let crate_id =
self.crate_loader
.process_path_extern(ident.name, ident.span);
let binding_id = binding.def().def_id();
if binding_id.krate == crate_id &&
binding_id.index == CRATE_DEF_INDEX {
self.session.buffer_lint(
lint::builtin::USE_CRATE_IN_MODULE,
id, ident.span,
"The crate can be used directly \
here.");
}
}
}

}
fully_local = fully_local && next_module.is_local();
first_resolution = false;
module = Some(next_module);
} else if def == Def::Err {
return PathResult::NonModule(err_path_resolution());
Expand Down

0 comments on commit c904d98

Please sign in to comment.