Skip to content

Commit 92b0324

Browse files
committed
librustc: Disallow use from reaching into impls or traits.
This can perhaps be restored in the future. For now this is a precursor to making typedefs work as expected.
1 parent ad5bfd6 commit 92b0324

File tree

5 files changed

+187
-67
lines changed

5 files changed

+187
-67
lines changed

src/librustc/middle/resolve.rs

Lines changed: 136 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,20 @@ pub enum AllowCapturingSelfFlag {
290290

291291
#[deriving(Eq)]
292292
enum NameSearchType {
293-
SearchItemsAndPublicImports, //< Search items and public imports.
294-
SearchItemsAndAllImports, //< Search items and all imports.
293+
/// We're doing a name search in order to resolve a `use` directive.
294+
ImportSearch,
295+
296+
/// We're doing a name search in order to resolve a path type, a path
297+
/// expression, or a path pattern. We can select public or private
298+
/// names.
299+
///
300+
/// XXX: This should be ripped out of resolve and handled later, in
301+
/// the privacy checking phase.
302+
PathPublicOrPrivateSearch,
303+
304+
/// We're doing a name search in order to resolve a path type, a path
305+
/// expression, or a path pattern. Allow only public names to be selected.
306+
PathPublicOnlySearch,
295307
}
296308

297309
pub enum BareIdentifierPatternResolution {
@@ -425,7 +437,10 @@ pub struct ImportState {
425437
}
426438
427439
pub fn ImportState() -> ImportState {
428-
ImportState{ used: false, warned: false }
440+
ImportState {
441+
used: false,
442+
warned: false,
443+
}
429444
}
430445
431446
/// The link from a module up to its nearest parent node.
@@ -440,6 +455,7 @@ pub enum ModuleKind {
440455
NormalModuleKind,
441456
ExternModuleKind,
442457
TraitModuleKind,
458+
ImplModuleKind,
443459
AnonymousModuleKind,
444460
}
445461
@@ -470,7 +486,6 @@ pub struct Module {
470486
//
471487
// There will be an anonymous module created around `g` with the ID of the
472488
// entry block for `f`.
473-
474489
anonymous_children: @mut HashMap<node_id,@mut Module>,
475490
476491
// The status of resolving each import in this module.
@@ -562,6 +577,38 @@ pub impl NameBindings {
562577
self.type_span = Some(sp);
563578
}
564579
580+
/// Sets the kind of the module, creating a new one if necessary.
581+
fn set_module_kind(@mut self,
582+
privacy: Privacy,
583+
parent_link: ParentLink,
584+
def_id: Option<def_id>,
585+
kind: ModuleKind,
586+
sp: span) {
587+
match self.type_def {
588+
None => {
589+
let module = @mut Module(parent_link, def_id, kind);
590+
self.type_def = Some(TypeNsDef {
591+
privacy: privacy,
592+
module_def: Some(module),
593+
type_def: None
594+
})
595+
}
596+
Some(type_def) => {
597+
match type_def.module_def {
598+
None => {
599+
let module = @mut Module(parent_link, def_id, kind);
600+
self.type_def = Some(TypeNsDef {
601+
privacy: privacy,
602+
module_def: Some(module),
603+
type_def: type_def.type_def
604+
})
605+
}
606+
Some(module_def) => module_def.kind = kind,
607+
}
608+
}
609+
}
610+
}
611+
565612
/// Records a type definition.
566613
fn define_type(@mut self, privacy: Privacy, def: def, sp: span) {
567614
// Merges the type with the existing type def or creates a new one.
@@ -1228,7 +1275,7 @@ pub impl Resolver {
12281275
name_bindings.define_module(Public,
12291276
parent_link,
12301277
Some(def_id),
1231-
TraitModuleKind,
1278+
ImplModuleKind,
12321279
sp);
12331280

12341281
let new_parent = ModuleReducedGraphParent(
@@ -1608,8 +1655,8 @@ pub impl Resolver {
16081655
// If this is a trait, add all the method names
16091656
// to the trait info.
16101657
1611-
let method_def_ids = get_trait_method_def_ids(self.session.cstore,
1612-
def_id);
1658+
let method_def_ids =
1659+
get_trait_method_def_ids(self.session.cstore, def_id);
16131660
let mut interned_method_names = HashSet::new();
16141661
for method_def_ids.each |&method_def_id| {
16151662
let (method_name, self_ty) =
@@ -1629,6 +1676,14 @@ pub impl Resolver {
16291676
self.trait_info.insert(def_id, interned_method_names);
16301677
16311678
child_name_bindings.define_type(Public, def, dummy_sp());
1679+
1680+
// Define a module if necessary.
1681+
let parent_link = self.get_parent_link(new_parent, ident);
1682+
child_name_bindings.set_module_kind(Public,
1683+
parent_link,
1684+
Some(def_id),
1685+
TraitModuleKind,
1686+
dummy_sp())
16321687
}
16331688
def_ty(_) => {
16341689
debug!("(building reduced graph for external \
@@ -1771,6 +1826,10 @@ pub impl Resolver {
17711826
// We already have a module. This
17721827
// is OK.
17731828
type_module = module_def;
1829+
1830+
// Mark it as an impl module if
1831+
// necessary.
1832+
type_module.kind = ImplModuleKind;
17741833
}
17751834
Some(_) | None => {
17761835
let parent_link =
@@ -1780,7 +1839,7 @@ pub impl Resolver {
17801839
Public,
17811840
parent_link,
17821841
Some(def),
1783-
NormalModuleKind,
1842+
ImplModuleKind,
17841843
dummy_sp());
17851844
type_module =
17861845
child_name_bindings.
@@ -1891,10 +1950,8 @@ pub impl Resolver {
18911950
// remain or unsuccessfully when no forward progress in resolving imports
18921951
// is made.
18931952

1894-
/**
1895-
* Resolves all imports for the crate. This method performs the fixed-
1896-
* point iteration.
1897-
*/
1953+
/// Resolves all imports for the crate. This method performs the fixed-
1954+
/// point iteration.
18981955
fn resolve_imports(@mut self) {
18991956
let mut i = 0;
19001957
let mut prev_unresolved_imports = 0;
@@ -2016,9 +2073,10 @@ pub impl Resolver {
20162073
/// don't know whether the name exists at the moment due to other
20172074
/// currently-unresolved imports, or success if we know the name exists.
20182075
/// If successful, the resolved bindings are written into the module.
2019-
fn resolve_import_for_module(@mut self, module_: @mut Module,
2076+
fn resolve_import_for_module(@mut self,
2077+
module_: @mut Module,
20202078
import_directive: @ImportDirective)
2021-
-> ResolveResult<()> {
2079+
-> ResolveResult<()> {
20222080
let mut resolution_result = Failed;
20232081
let module_path = &import_directive.module_path;
20242082

@@ -2032,10 +2090,11 @@ pub impl Resolver {
20322090
// Use the crate root.
20332091
Some(self.graph_root.get_module())
20342092
} else {
2035-
match self.resolve_module_path_for_import(module_,
2036-
*module_path,
2037-
DontUseLexicalScope,
2038-
import_directive.span) {
2093+
match self.resolve_module_path(module_,
2094+
*module_path,
2095+
DontUseLexicalScope,
2096+
import_directive.span,
2097+
ImportSearch) {
20392098

20402099
Failed => None,
20412100
Indeterminate => {
@@ -2122,7 +2181,7 @@ pub impl Resolver {
21222181
containing_module: @mut Module,
21232182
target: ident,
21242183
source: ident)
2125-
-> ResolveResult<()> {
2184+
-> ResolveResult<()> {
21262185
debug!("(resolving single import) resolving `%s` = `%s::%s` from \
21272186
`%s`",
21282187
*self.session.str_of(target),
@@ -2159,9 +2218,7 @@ pub impl Resolver {
21592218
// Unless we managed to find a result in both namespaces (unlikely),
21602219
// search imports as well.
21612220
match (value_result, type_result) {
2162-
(BoundResult(*), BoundResult(*)) => {
2163-
// Continue.
2164-
}
2221+
(BoundResult(*), BoundResult(*)) => {} // Continue.
21652222
_ => {
21662223
// If there is an unresolved glob at this point in the
21672224
// containing module, bail out. We don't know enough to be
@@ -2489,7 +2546,6 @@ pub impl Resolver {
24892546
// Resolve the module part of the path. This does not involve looking
24902547
// upward though scope chains; we simply resolve names directly in
24912548
// modules as we go.
2492-
24932549
while index < module_path_len {
24942550
let name = module_path[index];
24952551
match self.resolve_name_in_module(search_module,
@@ -2499,12 +2555,17 @@ pub impl Resolver {
24992555
Failed => {
25002556
let segment_name = self.session.str_of(name);
25012557
let module_name = self.module_to_str(search_module);
2502-
if module_name == ~"???" {
2503-
self.session.span_err(span {lo: span.lo, hi: span.lo +
2504-
BytePos(str::len(*segment_name)), expn_info:
2505-
span.expn_info}, fmt!("unresolved import. maybe \
2506-
a missing `extern mod %s`?",
2507-
*segment_name));
2558+
if "???" == module_name {
2559+
let span = span {
2560+
lo: span.lo,
2561+
hi: span.lo + BytePos(str::len(*segment_name)),
2562+
expn_info: span.expn_info,
2563+
};
2564+
self.session.span_err(span,
2565+
fmt!("unresolved import. maybe \
2566+
a missing `extern mod \
2567+
%s`?",
2568+
*segment_name));
25082569
return Failed;
25092570
}
25102571
self.session.span_err(span, fmt!("unresolved import: could not find `%s` in \
@@ -2533,8 +2594,22 @@ pub impl Resolver {
25332594
name)));
25342595
return Failed;
25352596
}
2536-
Some(copy module_def) => {
2537-
search_module = module_def;
2597+
Some(module_def) => {
2598+
// If we're doing the search for an
2599+
// import, do not allow traits and impls
2600+
// to be selected.
2601+
match (name_search_type,
2602+
module_def.kind) {
2603+
(ImportSearch, TraitModuleKind) |
2604+
(ImportSearch, ImplModuleKind) => {
2605+
self.session.span_err(
2606+
span,
2607+
~"cannot import from a trait \
2608+
or type implementation");
2609+
return Failed;
2610+
}
2611+
(_, _) => search_module = module_def,
2612+
}
25382613
}
25392614
}
25402615
}
@@ -2552,31 +2627,27 @@ pub impl Resolver {
25522627

25532628
index += 1;
25542629

2555-
// After the first element of the path, allow searching through
2556-
// items and imports unconditionally. This allows things like:
2557-
//
2558-
// pub mod core {
2559-
// pub use vec;
2560-
// }
2630+
// After the first element of the path, allow searching only
2631+
// through public identifiers.
25612632
//
2562-
// pub mod something_else {
2563-
// use core::vec;
2564-
// }
2565-
2566-
name_search_type = SearchItemsAndPublicImports;
2633+
// XXX: Rip this out and move it to the privacy checker.
2634+
if name_search_type == PathPublicOrPrivateSearch {
2635+
name_search_type = PathPublicOnlySearch
2636+
}
25672637
}
25682638

25692639
return Success(search_module);
25702640
}
25712641

25722642
/// Attempts to resolve the module part of an import directive or path
25732643
/// rooted at the given module.
2574-
fn resolve_module_path_for_import(@mut self,
2575-
module_: @mut Module,
2576-
module_path: &[ident],
2577-
use_lexical_scope: UseLexicalScopeFlag,
2578-
span: span)
2579-
-> ResolveResult<@mut Module> {
2644+
fn resolve_module_path(@mut self,
2645+
module_: @mut Module,
2646+
module_path: &[ident],
2647+
use_lexical_scope: UseLexicalScopeFlag,
2648+
span: span,
2649+
name_search_type: NameSearchType)
2650+
-> ResolveResult<@mut Module> {
25802651
let module_path_len = module_path.len();
25812652
assert!(module_path_len > 0);
25822653

@@ -2648,7 +2719,7 @@ pub impl Resolver {
26482719
module_path,
26492720
start_index,
26502721
span,
2651-
SearchItemsAndPublicImports)
2722+
name_search_type)
26522723
}
26532724
26542725
/// Invariant: This must only be called during main resolution, not during
@@ -2740,6 +2811,7 @@ pub impl Resolver {
27402811
}
27412812
ExternModuleKind |
27422813
TraitModuleKind |
2814+
ImplModuleKind |
27432815
AnonymousModuleKind => {
27442816
search_module = parent_module_node;
27452817
}
@@ -2759,7 +2831,7 @@ pub impl Resolver {
27592831
match self.resolve_name_in_module(search_module,
27602832
name,
27612833
namespace,
2762-
SearchItemsAndAllImports) {
2834+
PathPublicOrPrivateSearch) {
27632835
Failed => {
27642836
// Continue up the search chain.
27652837
}
@@ -2840,6 +2912,7 @@ pub impl Resolver {
28402912
NormalModuleKind => return Some(new_module),
28412913
ExternModuleKind |
28422914
TraitModuleKind |
2915+
ImplModuleKind |
28432916
AnonymousModuleKind => module_ = new_module,
28442917
}
28452918
}
@@ -2856,7 +2929,10 @@ pub impl Resolver {
28562929
-> @mut Module {
28572930
match module_.kind {
28582931
NormalModuleKind => return module_,
2859-
ExternModuleKind | TraitModuleKind | AnonymousModuleKind => {
2932+
ExternModuleKind |
2933+
TraitModuleKind |
2934+
ImplModuleKind |
2935+
AnonymousModuleKind => {
28602936
match self.get_nearest_normal_module_parent(module_) {
28612937
None => module_,
28622938
Some(new_module) => new_module
@@ -2940,7 +3016,8 @@ pub impl Resolver {
29403016

29413017
// If this is a search of all imports, we should be done with glob
29423018
// resolution at this point.
2943-
if name_search_type == SearchItemsAndAllImports {
3019+
if name_search_type == PathPublicOrPrivateSearch ||
3020+
name_search_type == PathPublicOnlySearch {
29443021
assert!(module_.glob_count == 0);
29453022
}
29463023

@@ -2962,7 +3039,7 @@ pub impl Resolver {
29623039
}
29633040
Some(target)
29643041
if name_search_type ==
2965-
SearchItemsAndAllImports ||
3042+
PathPublicOrPrivateSearch ||
29663043
import_resolution.privacy == Public => {
29673044
debug!("(resolving name in module) resolved to \
29683045
import");
@@ -4488,10 +4565,11 @@ pub impl Resolver {
44884565
let module_path_idents = self.intern_module_part_of_path(path);
44894566
44904567
let containing_module;
4491-
match self.resolve_module_path_for_import(self.current_module,
4492-
module_path_idents,
4493-
UseLexicalScope,
4494-
path.span) {
4568+
match self.resolve_module_path(self.current_module,
4569+
module_path_idents,
4570+
UseLexicalScope,
4571+
path.span,
4572+
PathPublicOnlySearch) {
44954573
Failed => {
44964574
self.session.span_err(path.span,
44974575
fmt!("use of undeclared module `%s`",
@@ -4540,7 +4618,7 @@ pub impl Resolver {
45404618
module_path_idents,
45414619
0,
45424620
path.span,
4543-
SearchItemsAndAllImports) {
4621+
PathPublicOrPrivateSearch) {
45444622
Failed => {
45454623
self.session.span_err(path.span,
45464624
fmt!("use of undeclared module `::%s`",

0 commit comments

Comments
 (0)