Skip to content

Commit b0e13dc

Browse files
committed
Treat extern crates more like imports (pure refactoring).
1 parent 8021ede commit b0e13dc

File tree

3 files changed

+52
-39
lines changed

3 files changed

+52
-39
lines changed

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
//! any imports resolved.
1515
1616
use macros::{InvocationData, LegacyScope};
17+
use resolve_imports::ImportDirective;
1718
use resolve_imports::ImportDirectiveSubclass::{self, GlobImport};
1819
use {Module, ModuleS, ModuleKind};
1920
use Namespace::{self, TypeNS, ValueNS};
@@ -237,11 +238,22 @@ impl<'b> Resolver<'b> {
237238
index: CRATE_DEF_INDEX,
238239
};
239240
let module = self.arenas.alloc_module(ModuleS {
240-
extern_crate_id: Some(item.id),
241241
populated: Cell::new(false),
242242
..ModuleS::new(Some(parent), ModuleKind::Def(Def::Mod(def_id), name))
243243
});
244-
self.define(parent, name, TypeNS, (module, sp, vis));
244+
let binding = (module, sp, ty::Visibility::Public).to_name_binding();
245+
let binding = self.arenas.alloc_name_binding(binding);
246+
let directive = self.arenas.alloc_import_directive(ImportDirective {
247+
id: item.id,
248+
parent: parent,
249+
imported_module: Cell::new(Some(module)),
250+
subclass: ImportDirectiveSubclass::ExternCrate,
251+
span: item.span,
252+
module_path: Vec::new(),
253+
vis: Cell::new(vis),
254+
});
255+
let imported_binding = self.import(binding, directive);
256+
self.define(parent, name, TypeNS, imported_binding);
245257
self.populate_module_if_necessary(module);
246258
module
247259
} else {

src/librustc_resolve/lib.rs

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ use std::fmt;
7676
use std::mem::replace;
7777
use std::rc::Rc;
7878

79-
use resolve_imports::{ImportDirective, NameResolution};
79+
use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution};
8080
use macros::{InvocationData, LegacyBinding, LegacyScope};
8181

8282
// NB: This module needs to be declared first so diagnostics are
@@ -796,10 +796,6 @@ pub struct ModuleS<'a> {
796796
// The node id of the closest normal module (`mod`) ancestor (including this module).
797797
normal_ancestor_id: Option<NodeId>,
798798

799-
// If the module is an extern crate, `def` is root of the external crate and `extern_crate_id`
800-
// is the NodeId of the local `extern crate` item (otherwise, `extern_crate_id` is None).
801-
extern_crate_id: Option<NodeId>,
802-
803799
resolutions: RefCell<FxHashMap<(Name, Namespace), &'a RefCell<NameResolution<'a>>>>,
804800

805801
no_implicit_prelude: bool,
@@ -824,7 +820,6 @@ impl<'a> ModuleS<'a> {
824820
parent: parent,
825821
kind: kind,
826822
normal_ancestor_id: None,
827-
extern_crate_id: None,
828823
resolutions: RefCell::new(FxHashMap()),
829824
no_implicit_prelude: false,
830825
glob_importers: RefCell::new(Vec::new()),
@@ -953,7 +948,14 @@ impl<'a> NameBinding<'a> {
953948
}
954949

955950
fn is_extern_crate(&self) -> bool {
956-
self.module().ok().and_then(|module| module.extern_crate_id).is_some()
951+
match self.kind {
952+
NameBindingKind::Import {
953+
directive: &ImportDirective {
954+
subclass: ImportDirectiveSubclass::ExternCrate, ..
955+
}, ..
956+
} => true,
957+
_ => false,
958+
}
957959
}
958960

959961
fn is_import(&self) -> bool {
@@ -3233,7 +3235,7 @@ impl<'a> Resolver<'a> {
32333235
in_module.for_each_child(|name, ns, name_binding| {
32343236

32353237
// avoid imports entirely
3236-
if name_binding.is_import() { return; }
3238+
if name_binding.is_import() && !name_binding.is_extern_crate() { return; }
32373239

32383240
// collect results based on the filter function
32393241
if name == lookup_name && ns == namespace {
@@ -3269,21 +3271,11 @@ impl<'a> Resolver<'a> {
32693271
// collect submodules to explore
32703272
if let Ok(module) = name_binding.module() {
32713273
// form the path
3272-
let path_segments = match module.kind {
3273-
_ if module.parent.is_none() => path_segments.clone(),
3274-
ModuleKind::Def(_, name) => {
3275-
let mut paths = path_segments.clone();
3276-
let ident = Ident::with_empty_ctxt(name);
3277-
let params = PathParameters::none();
3278-
let segm = PathSegment {
3279-
identifier: ident,
3280-
parameters: params,
3281-
};
3282-
paths.push(segm);
3283-
paths
3284-
}
3285-
_ => bug!(),
3286-
};
3274+
let mut path_segments = path_segments.clone();
3275+
path_segments.push(PathSegment {
3276+
identifier: Ident::with_empty_ctxt(name),
3277+
parameters: PathParameters::none(),
3278+
});
32873279

32883280
if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
32893281
// add the module to the lookup
@@ -3369,7 +3361,10 @@ impl<'a> Resolver<'a> {
33693361
if !reported_spans.insert(span) { continue }
33703362
if binding.is_extern_crate() {
33713363
// Warn when using an inaccessible extern crate.
3372-
let node_id = binding.module().unwrap().extern_crate_id.unwrap();
3364+
let node_id = match binding.kind {
3365+
NameBindingKind::Import { directive, .. } => directive.id,
3366+
_ => unreachable!(),
3367+
};
33733368
let msg = format!("extern crate `{}` is private", name);
33743369
self.session.add_lint(lint::builtin::INACCESSIBLE_EXTERN_CRATE, node_id, span, msg);
33753370
} else {
@@ -3415,7 +3410,7 @@ impl<'a> Resolver<'a> {
34153410
_ => "enum",
34163411
};
34173412

3418-
let (participle, noun) = match old_binding.is_import() || old_binding.is_extern_crate() {
3413+
let (participle, noun) = match old_binding.is_import() {
34193414
true => ("imported", "import"),
34203415
false => ("defined", "definition"),
34213416
};
@@ -3424,7 +3419,7 @@ impl<'a> Resolver<'a> {
34243419
let msg = {
34253420
let kind = match (ns, old_binding.module()) {
34263421
(ValueNS, _) => "a value",
3427-
(TypeNS, Ok(module)) if module.extern_crate_id.is_some() => "an extern crate",
3422+
(TypeNS, _) if old_binding.is_extern_crate() => "an extern crate",
34283423
(TypeNS, Ok(module)) if module.is_normal() => "a module",
34293424
(TypeNS, Ok(module)) if module.is_trait() => "a trait",
34303425
(TypeNS, _) => "a type",
@@ -3439,7 +3434,7 @@ impl<'a> Resolver<'a> {
34393434
e.span_label(span, &format!("`{}` was already imported", name));
34403435
e
34413436
},
3442-
(true, _) | (_, true) if binding.is_import() || old_binding.is_import() => {
3437+
(true, _) | (_, true) if binding.is_import() && old_binding.is_import() => {
34433438
let mut e = struct_span_err!(self.session, span, E0254, "{}", msg);
34443439
e.span_label(span, &"already imported");
34453440
e

src/librustc_resolve/resolve_imports.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ pub enum ImportDirectiveSubclass<'a> {
5151
max_vis: Cell<ty::Visibility>, // The visibility of the greatest reexport.
5252
// n.b. `max_vis` is only used in `finalize_import` to check for reexport errors.
5353
},
54+
ExternCrate,
5455
}
5556

5657
impl<'a> ImportDirectiveSubclass<'a> {
@@ -68,12 +69,12 @@ impl<'a> ImportDirectiveSubclass<'a> {
6869
#[derive(Debug,Clone)]
6970
pub struct ImportDirective<'a> {
7071
pub id: NodeId,
71-
parent: Module<'a>,
72-
module_path: Vec<Ident>,
73-
imported_module: Cell<Option<Module<'a>>>, // the resolution of `module_path`
74-
subclass: ImportDirectiveSubclass<'a>,
75-
span: Span,
76-
vis: Cell<ty::Visibility>,
72+
pub parent: Module<'a>,
73+
pub module_path: Vec<Ident>,
74+
pub imported_module: Cell<Option<Module<'a>>>, // the resolution of `module_path`
75+
pub subclass: ImportDirectiveSubclass<'a>,
76+
pub span: Span,
77+
pub vis: Cell<ty::Visibility>,
7778
}
7879

7980
impl<'a> ImportDirective<'a> {
@@ -169,7 +170,8 @@ impl<'a> Resolver<'a> {
169170
let new_import_semantics = self.new_import_semantics;
170171
let is_disallowed_private_import = |binding: &NameBinding| {
171172
!new_import_semantics && !allow_private_imports && // disallowed
172-
binding.vis != ty::Visibility::Public && binding.is_import() // non-`pub` import
173+
binding.vis != ty::Visibility::Public && binding.is_import() && // non-`pub` import
174+
!binding.is_extern_crate() // not an `extern crate`
173175
};
174176

175177
if let Some(span) = record_used {
@@ -237,7 +239,7 @@ impl<'a> Resolver<'a> {
237239
};
238240
let name = match directive.subclass {
239241
SingleImport { source, .. } => source,
240-
GlobImport { .. } => unreachable!(),
242+
_ => unreachable!(),
241243
};
242244
match self.resolve_name_in_module(module, name, ns, true, None) {
243245
Failed(_) => {}
@@ -280,13 +282,14 @@ impl<'a> Resolver<'a> {
280282
// which are not relevant to import resolution.
281283
GlobImport { is_prelude: true, .. } => {}
282284
GlobImport { .. } => self.current_module.globs.borrow_mut().push(directive),
285+
_ => unreachable!(),
283286
}
284287
}
285288

286289
// Given a binding and an import directive that resolves to it,
287290
// return the corresponding binding defined by the import directive.
288-
fn import(&mut self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>)
289-
-> NameBinding<'a> {
291+
pub fn import(&mut self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>)
292+
-> NameBinding<'a> {
290293
let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) ||
291294
!directive.is_glob() && binding.is_extern_crate() { // c.f. `PRIVATE_IN_PUBLIC`
292295
directive.vis.get()
@@ -529,6 +532,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
529532
self.resolve_glob_import(directive);
530533
return Success(());
531534
}
535+
_ => unreachable!(),
532536
};
533537

534538
let mut indeterminate = false;
@@ -616,6 +620,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
616620
}
617621
return Success(());
618622
}
623+
_ => unreachable!(),
619624
};
620625

621626
for &(ns, result) in &[(ValueNS, value_result), (TypeNS, type_result)] {
@@ -831,5 +836,6 @@ fn import_directive_subclass_to_string(subclass: &ImportDirectiveSubclass) -> St
831836
match *subclass {
832837
SingleImport { source, .. } => source.to_string(),
833838
GlobImport { .. } => "*".to_string(),
839+
ExternCrate => "<extern crate>".to_string(),
834840
}
835841
}

0 commit comments

Comments
 (0)