Skip to content

Commit ae690f8

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 8257528 commit ae690f8

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.
@@ -560,6 +575,38 @@ pub impl NameBindings {
560575
}
561576
}
562577

578+
/// Sets the kind of the module, creating a new one if necessary.
579+
fn set_module_kind(@mut self,
580+
privacy: Privacy,
581+
parent_link: ParentLink,
582+
def_id: Option<def_id>,
583+
kind: ModuleKind,
584+
sp: span) {
585+
match self.type_def {
586+
None => {
587+
let module = @mut Module(parent_link, def_id, kind);
588+
self.type_def = Some(TypeNsDef {
589+
privacy: privacy,
590+
module_def: Some(module),
591+
type_def: None
592+
})
593+
}
594+
Some(type_def) => {
595+
match type_def.module_def {
596+
None => {
597+
let module = @mut Module(parent_link, def_id, kind);
598+
self.type_def = Some(TypeNsDef {
599+
privacy: privacy,
600+
module_def: Some(module),
601+
type_def: type_def.type_def
602+
})
603+
}
604+
Some(module_def) => module_def.kind = kind,
605+
}
606+
}
607+
}
608+
}
609+
563610
/// Records a type definition.
564611
fn define_type(@mut self, privacy: Privacy, def: def, sp: span) {
565612
// Merges the type with the existing type def or creates a new one.
@@ -1234,7 +1281,7 @@ pub impl Resolver {
12341281
name_bindings.define_module(Public,
12351282
parent_link,
12361283
Some(def_id),
1237-
TraitModuleKind,
1284+
ImplModuleKind,
12381285
sp);
12391286

12401287
let new_parent = ModuleReducedGraphParent(
@@ -1614,8 +1661,8 @@ pub impl Resolver {
16141661
// If this is a trait, add all the method names
16151662
// to the trait info.
16161663

1617-
let method_def_ids = get_trait_method_def_ids(self.session.cstore,
1618-
def_id);
1664+
let method_def_ids =
1665+
get_trait_method_def_ids(self.session.cstore, def_id);
16191666
let mut interned_method_names = HashSet::new();
16201667
for method_def_ids.each |&method_def_id| {
16211668
let (method_name, explicit_self) =
@@ -1635,6 +1682,14 @@ pub impl Resolver {
16351682
self.trait_info.insert(def_id, interned_method_names);
16361683

16371684
child_name_bindings.define_type(Public, def, dummy_sp());
1685+
1686+
// Define a module if necessary.
1687+
let parent_link = self.get_parent_link(new_parent, ident);
1688+
child_name_bindings.set_module_kind(Public,
1689+
parent_link,
1690+
Some(def_id),
1691+
TraitModuleKind,
1692+
dummy_sp())
16381693
}
16391694
def_ty(_) => {
16401695
debug!("(building reduced graph for external \
@@ -1777,6 +1832,10 @@ pub impl Resolver {
17771832
// We already have a module. This
17781833
// is OK.
17791834
type_module = module_def;
1835+
1836+
// Mark it as an impl module if
1837+
// necessary.
1838+
type_module.kind = ImplModuleKind;
17801839
}
17811840
Some(_) | None => {
17821841
let parent_link =
@@ -1786,7 +1845,7 @@ pub impl Resolver {
17861845
Public,
17871846
parent_link,
17881847
Some(def),
1789-
NormalModuleKind,
1848+
ImplModuleKind,
17901849
dummy_sp());
17911850
type_module =
17921851
child_name_bindings.
@@ -1897,10 +1956,8 @@ pub impl Resolver {
18971956
// remain or unsuccessfully when no forward progress in resolving imports
18981957
// is made.
18991958

1900-
/**
1901-
* Resolves all imports for the crate. This method performs the fixed-
1902-
* point iteration.
1903-
*/
1959+
/// Resolves all imports for the crate. This method performs the fixed-
1960+
/// point iteration.
19041961
fn resolve_imports(@mut self) {
19051962
let mut i = 0;
19061963
let mut prev_unresolved_imports = 0;
@@ -2022,9 +2079,10 @@ pub impl Resolver {
20222079
/// don't know whether the name exists at the moment due to other
20232080
/// currently-unresolved imports, or success if we know the name exists.
20242081
/// If successful, the resolved bindings are written into the module.
2025-
fn resolve_import_for_module(@mut self, module_: @mut Module,
2082+
fn resolve_import_for_module(@mut self,
2083+
module_: @mut Module,
20262084
import_directive: @ImportDirective)
2027-
-> ResolveResult<()> {
2085+
-> ResolveResult<()> {
20282086
let mut resolution_result = Failed;
20292087
let module_path = &import_directive.module_path;
20302088

@@ -2038,10 +2096,11 @@ pub impl Resolver {
20382096
// Use the crate root.
20392097
Some(self.graph_root.get_module())
20402098
} else {
2041-
match self.resolve_module_path_for_import(module_,
2042-
*module_path,
2043-
DontUseLexicalScope,
2044-
import_directive.span) {
2099+
match self.resolve_module_path(module_,
2100+
*module_path,
2101+
DontUseLexicalScope,
2102+
import_directive.span,
2103+
ImportSearch) {
20452104

20462105
Failed => None,
20472106
Indeterminate => {
@@ -2129,7 +2188,7 @@ pub impl Resolver {
21292188
target: ident,
21302189
source: ident,
21312190
span: span)
2132-
-> ResolveResult<()> {
2191+
-> ResolveResult<()> {
21332192
debug!("(resolving single import) resolving `%s` = `%s::%s` from \
21342193
`%s`",
21352194
*self.session.str_of(target),
@@ -2166,9 +2225,7 @@ pub impl Resolver {
21662225
// Unless we managed to find a result in both namespaces (unlikely),
21672226
// search imports as well.
21682227
match (value_result, type_result) {
2169-
(BoundResult(*), BoundResult(*)) => {
2170-
// Continue.
2171-
}
2228+
(BoundResult(*), BoundResult(*)) => {} // Continue.
21722229
_ => {
21732230
// If there is an unresolved glob at this point in the
21742231
// containing module, bail out. We don't know enough to be
@@ -2496,7 +2553,6 @@ pub impl Resolver {
24962553
// Resolve the module part of the path. This does not involve looking
24972554
// upward though scope chains; we simply resolve names directly in
24982555
// modules as we go.
2499-
25002556
while index < module_path_len {
25012557
let name = module_path[index];
25022558
match self.resolve_name_in_module(search_module,
@@ -2506,12 +2562,17 @@ pub impl Resolver {
25062562
Failed => {
25072563
let segment_name = self.session.str_of(name);
25082564
let module_name = self.module_to_str(search_module);
2509-
if module_name == ~"???" {
2510-
self.session.span_err(span {lo: span.lo, hi: span.lo +
2511-
BytePos(str::len(*segment_name)), expn_info:
2512-
span.expn_info}, fmt!("unresolved import. maybe \
2513-
a missing `extern mod %s`?",
2514-
*segment_name));
2565+
if "???" == module_name {
2566+
let span = span {
2567+
lo: span.lo,
2568+
hi: span.lo + BytePos(str::len(*segment_name)),
2569+
expn_info: span.expn_info,
2570+
};
2571+
self.session.span_err(span,
2572+
fmt!("unresolved import. maybe \
2573+
a missing `extern mod \
2574+
%s`?",
2575+
*segment_name));
25152576
return Failed;
25162577
}
25172578
self.session.span_err(span, fmt!("unresolved import: could not find `%s` in \
@@ -2540,8 +2601,22 @@ pub impl Resolver {
25402601
name)));
25412602
return Failed;
25422603
}
2543-
Some(copy module_def) => {
2544-
search_module = module_def;
2604+
Some(module_def) => {
2605+
// If we're doing the search for an
2606+
// import, do not allow traits and impls
2607+
// to be selected.
2608+
match (name_search_type,
2609+
module_def.kind) {
2610+
(ImportSearch, TraitModuleKind) |
2611+
(ImportSearch, ImplModuleKind) => {
2612+
self.session.span_err(
2613+
span,
2614+
~"cannot import from a trait \
2615+
or type implementation");
2616+
return Failed;
2617+
}
2618+
(_, _) => search_module = module_def,
2619+
}
25452620
}
25462621
}
25472622
}
@@ -2559,31 +2634,27 @@ pub impl Resolver {
25592634

25602635
index += 1;
25612636

2562-
// After the first element of the path, allow searching through
2563-
// items and imports unconditionally. This allows things like:
2564-
//
2565-
// pub mod core {
2566-
// pub use vec;
2567-
// }
2637+
// After the first element of the path, allow searching only
2638+
// through public identifiers.
25682639
//
2569-
// pub mod something_else {
2570-
// use core::vec;
2571-
// }
2572-
2573-
name_search_type = SearchItemsAndPublicImports;
2640+
// XXX: Rip this out and move it to the privacy checker.
2641+
if name_search_type == PathPublicOrPrivateSearch {
2642+
name_search_type = PathPublicOnlySearch
2643+
}
25742644
}
25752645

25762646
return Success(search_module);
25772647
}
25782648

25792649
/// Attempts to resolve the module part of an import directive or path
25802650
/// rooted at the given module.
2581-
fn resolve_module_path_for_import(@mut self,
2582-
module_: @mut Module,
2583-
module_path: &[ident],
2584-
use_lexical_scope: UseLexicalScopeFlag,
2585-
span: span)
2586-
-> ResolveResult<@mut Module> {
2651+
fn resolve_module_path(@mut self,
2652+
module_: @mut Module,
2653+
module_path: &[ident],
2654+
use_lexical_scope: UseLexicalScopeFlag,
2655+
span: span,
2656+
name_search_type: NameSearchType)
2657+
-> ResolveResult<@mut Module> {
25872658
let module_path_len = module_path.len();
25882659
assert!(module_path_len > 0);
25892660

@@ -2666,7 +2737,7 @@ pub impl Resolver {
26662737
module_path,
26672738
start_index,
26682739
span,
2669-
SearchItemsAndPublicImports)
2740+
name_search_type)
26702741
}
26712742

26722743
/// Invariant: This must only be called during main resolution, not during
@@ -2758,6 +2829,7 @@ pub impl Resolver {
27582829
}
27592830
ExternModuleKind |
27602831
TraitModuleKind |
2832+
ImplModuleKind |
27612833
AnonymousModuleKind => {
27622834
search_module = parent_module_node;
27632835
}
@@ -2777,7 +2849,7 @@ pub impl Resolver {
27772849
match self.resolve_name_in_module(search_module,
27782850
name,
27792851
namespace,
2780-
SearchItemsAndAllImports) {
2852+
PathPublicOrPrivateSearch) {
27812853
Failed => {
27822854
// Continue up the search chain.
27832855
}
@@ -2858,6 +2930,7 @@ pub impl Resolver {
28582930
NormalModuleKind => return Some(new_module),
28592931
ExternModuleKind |
28602932
TraitModuleKind |
2933+
ImplModuleKind |
28612934
AnonymousModuleKind => module_ = new_module,
28622935
}
28632936
}
@@ -2874,7 +2947,10 @@ pub impl Resolver {
28742947
-> @mut Module {
28752948
match module_.kind {
28762949
NormalModuleKind => return module_,
2877-
ExternModuleKind | TraitModuleKind | AnonymousModuleKind => {
2950+
ExternModuleKind |
2951+
TraitModuleKind |
2952+
ImplModuleKind |
2953+
AnonymousModuleKind => {
28782954
match self.get_nearest_normal_module_parent(module_) {
28792955
None => module_,
28802956
Some(new_module) => new_module
@@ -2958,7 +3034,8 @@ pub impl Resolver {
29583034

29593035
// If this is a search of all imports, we should be done with glob
29603036
// resolution at this point.
2961-
if name_search_type == SearchItemsAndAllImports {
3037+
if name_search_type == PathPublicOrPrivateSearch ||
3038+
name_search_type == PathPublicOnlySearch {
29623039
assert!(module_.glob_count == 0);
29633040
}
29643041

@@ -2980,7 +3057,7 @@ pub impl Resolver {
29803057
}
29813058
Some(target)
29823059
if name_search_type ==
2983-
SearchItemsAndAllImports ||
3060+
PathPublicOrPrivateSearch ||
29843061
import_resolution.privacy == Public => {
29853062
debug!("(resolving name in module) resolved to \
29863063
import");
@@ -4506,10 +4583,11 @@ pub impl Resolver {
45064583
let module_path_idents = self.intern_module_part_of_path(path);
45074584

45084585
let containing_module;
4509-
match self.resolve_module_path_for_import(self.current_module,
4510-
module_path_idents,
4511-
UseLexicalScope,
4512-
path.span) {
4586+
match self.resolve_module_path(self.current_module,
4587+
module_path_idents,
4588+
UseLexicalScope,
4589+
path.span,
4590+
PathPublicOnlySearch) {
45134591
Failed => {
45144592
self.session.span_err(path.span,
45154593
fmt!("use of undeclared module `%s`",
@@ -4558,7 +4636,7 @@ pub impl Resolver {
45584636
module_path_idents,
45594637
0,
45604638
path.span,
4561-
SearchItemsAndAllImports) {
4639+
PathPublicOrPrivateSearch) {
45624640
Failed => {
45634641
self.session.span_err(path.span,
45644642
fmt!("use of undeclared module `::%s`",

0 commit comments

Comments
 (0)