Skip to content

Commit ca9bb2d

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 2915187 commit ca9bb2d

File tree

5 files changed

+187
-65
lines changed

5 files changed

+187
-65
lines changed

src/librustc/middle/resolve.rs

Lines changed: 136 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,20 @@ pub enum AllowCapturingSelfFlag {
255255

256256
#[deriving(Eq)]
257257
enum NameSearchType {
258-
SearchItemsAndPublicImports, //< Search items and public imports.
259-
SearchItemsAndAllImports, //< Search items and all imports.
258+
/// We're doing a name search in order to resolve a `use` directive.
259+
ImportSearch,
260+
261+
/// We're doing a name search in order to resolve a path type, a path
262+
/// expression, or a path pattern. We can select public or private
263+
/// names.
264+
///
265+
/// XXX: This should be ripped out of resolve and handled later, in
266+
/// the privacy checking phase.
267+
PathPublicOrPrivateSearch,
268+
269+
/// We're doing a name search in order to resolve a path type, a path
270+
/// expression, or a path pattern. Allow only public names to be selected.
271+
PathPublicOnlySearch,
260272
}
261273

262274
pub enum BareIdentifierPatternResolution {
@@ -394,6 +406,7 @@ pub enum ModuleKind {
394406
NormalModuleKind,
395407
ExternModuleKind,
396408
TraitModuleKind,
409+
ImplModuleKind,
397410
AnonymousModuleKind,
398411
}
399412

@@ -424,7 +437,6 @@ pub struct Module {
424437
//
425438
// There will be an anonymous module created around `g` with the ID of the
426439
// entry block for `f`.
427-
428440
anonymous_children: @mut HashMap<node_id,@mut Module>,
429441

430442
// The status of resolving each import in this module.
@@ -514,6 +526,38 @@ pub impl NameBindings {
514526
}
515527
}
516528

529+
/// Sets the kind of the module, creating a new one if necessary.
530+
fn set_module_kind(@mut self,
531+
privacy: Privacy,
532+
parent_link: ParentLink,
533+
def_id: Option<def_id>,
534+
kind: ModuleKind,
535+
sp: span) {
536+
match self.type_def {
537+
None => {
538+
let module = @mut Module(parent_link, def_id, kind);
539+
self.type_def = Some(TypeNsDef {
540+
privacy: privacy,
541+
module_def: Some(module),
542+
type_def: None
543+
})
544+
}
545+
Some(type_def) => {
546+
match type_def.module_def {
547+
None => {
548+
let module = @mut Module(parent_link, def_id, kind);
549+
self.type_def = Some(TypeNsDef {
550+
privacy: privacy,
551+
module_def: Some(module),
552+
type_def: type_def.type_def
553+
})
554+
}
555+
Some(module_def) => module_def.kind = kind,
556+
}
557+
}
558+
}
559+
}
560+
517561
/// Records a type definition.
518562
fn define_type(@mut self, privacy: Privacy, def: def, sp: span) {
519563
// Merges the type with the existing type def or creates a new one.
@@ -1191,7 +1235,7 @@ pub impl Resolver {
11911235
name_bindings.define_module(Public,
11921236
parent_link,
11931237
Some(def_id),
1194-
TraitModuleKind,
1238+
ImplModuleKind,
11951239
sp);
11961240

11971241
let new_parent = ModuleReducedGraphParent(
@@ -1579,8 +1623,8 @@ pub impl Resolver {
15791623
// If this is a trait, add all the method names
15801624
// to the trait info.
15811625

1582-
let method_def_ids = get_trait_method_def_ids(self.session.cstore,
1583-
def_id);
1626+
let method_def_ids =
1627+
get_trait_method_def_ids(self.session.cstore, def_id);
15841628
let mut interned_method_names = HashSet::new();
15851629
for method_def_ids.each |&method_def_id| {
15861630
let (method_name, explicit_self) =
@@ -1608,6 +1652,14 @@ pub impl Resolver {
16081652
}
16091653

16101654
child_name_bindings.define_type(Public, def, dummy_sp());
1655+
1656+
// Define a module if necessary.
1657+
let parent_link = self.get_parent_link(new_parent, ident);
1658+
child_name_bindings.set_module_kind(Public,
1659+
parent_link,
1660+
Some(def_id),
1661+
TraitModuleKind,
1662+
dummy_sp())
16111663
}
16121664
def_ty(_) => {
16131665
debug!("(building reduced graph for external \
@@ -1750,6 +1802,10 @@ pub impl Resolver {
17501802
// We already have a module. This
17511803
// is OK.
17521804
type_module = module_def;
1805+
1806+
// Mark it as an impl module if
1807+
// necessary.
1808+
type_module.kind = ImplModuleKind;
17531809
}
17541810
Some(_) | None => {
17551811
let parent_link =
@@ -1759,7 +1815,7 @@ pub impl Resolver {
17591815
Public,
17601816
parent_link,
17611817
Some(def),
1762-
NormalModuleKind,
1818+
ImplModuleKind,
17631819
dummy_sp());
17641820
type_module =
17651821
child_name_bindings.
@@ -1866,10 +1922,8 @@ pub impl Resolver {
18661922
// remain or unsuccessfully when no forward progress in resolving imports
18671923
// is made.
18681924

1869-
/**
1870-
* Resolves all imports for the crate. This method performs the fixed-
1871-
* point iteration.
1872-
*/
1925+
/// Resolves all imports for the crate. This method performs the fixed-
1926+
/// point iteration.
18731927
fn resolve_imports(@mut self) {
18741928
let mut i = 0;
18751929
let mut prev_unresolved_imports = 0;
@@ -1991,9 +2045,10 @@ pub impl Resolver {
19912045
/// don't know whether the name exists at the moment due to other
19922046
/// currently-unresolved imports, or success if we know the name exists.
19932047
/// If successful, the resolved bindings are written into the module.
1994-
fn resolve_import_for_module(@mut self, module_: @mut Module,
2048+
fn resolve_import_for_module(@mut self,
2049+
module_: @mut Module,
19952050
import_directive: @ImportDirective)
1996-
-> ResolveResult<()> {
2051+
-> ResolveResult<()> {
19972052
let mut resolution_result = Failed;
19982053
let module_path = &import_directive.module_path;
19992054

@@ -2007,10 +2062,11 @@ pub impl Resolver {
20072062
// Use the crate root.
20082063
Some(self.graph_root.get_module())
20092064
} else {
2010-
match self.resolve_module_path_for_import(module_,
2011-
*module_path,
2012-
DontUseLexicalScope,
2013-
import_directive.span) {
2065+
match self.resolve_module_path(module_,
2066+
*module_path,
2067+
DontUseLexicalScope,
2068+
import_directive.span,
2069+
ImportSearch) {
20142070

20152071
Failed => None,
20162072
Indeterminate => {
@@ -2097,7 +2153,7 @@ pub impl Resolver {
20972153
target: ident,
20982154
source: ident,
20992155
span: span)
2100-
-> ResolveResult<()> {
2156+
-> ResolveResult<()> {
21012157
debug!("(resolving single import) resolving `%s` = `%s::%s` from \
21022158
`%s`",
21032159
*self.session.str_of(target),
@@ -2134,9 +2190,7 @@ pub impl Resolver {
21342190
// Unless we managed to find a result in both namespaces (unlikely),
21352191
// search imports as well.
21362192
match (value_result, type_result) {
2137-
(BoundResult(*), BoundResult(*)) => {
2138-
// Continue.
2139-
}
2193+
(BoundResult(*), BoundResult(*)) => {} // Continue.
21402194
_ => {
21412195
// If there is an unresolved glob at this point in the
21422196
// containing module, bail out. We don't know enough to be
@@ -2460,7 +2514,6 @@ pub impl Resolver {
24602514
// Resolve the module part of the path. This does not involve looking
24612515
// upward though scope chains; we simply resolve names directly in
24622516
// modules as we go.
2463-
24642517
while index < module_path_len {
24652518
let name = module_path[index];
24662519
match self.resolve_name_in_module(search_module,
@@ -2470,12 +2523,17 @@ pub impl Resolver {
24702523
Failed => {
24712524
let segment_name = self.session.str_of(name);
24722525
let module_name = self.module_to_str(search_module);
2473-
if module_name == ~"???" {
2474-
self.session.span_err(span {lo: span.lo, hi: span.lo +
2475-
BytePos(str::len(*segment_name)), expn_info:
2476-
span.expn_info}, fmt!("unresolved import. maybe \
2477-
a missing `extern mod %s`?",
2478-
*segment_name));
2526+
if "???" == module_name {
2527+
let span = span {
2528+
lo: span.lo,
2529+
hi: span.lo + BytePos(str::len(*segment_name)),
2530+
expn_info: span.expn_info,
2531+
};
2532+
self.session.span_err(span,
2533+
fmt!("unresolved import. maybe \
2534+
a missing `extern mod \
2535+
%s`?",
2536+
*segment_name));
24792537
return Failed;
24802538
}
24812539
self.session.span_err(span, fmt!("unresolved import: could not find `%s` in \
@@ -2504,8 +2562,22 @@ pub impl Resolver {
25042562
name)));
25052563
return Failed;
25062564
}
2507-
Some(copy module_def) => {
2508-
search_module = module_def;
2565+
Some(module_def) => {
2566+
// If we're doing the search for an
2567+
// import, do not allow traits and impls
2568+
// to be selected.
2569+
match (name_search_type,
2570+
module_def.kind) {
2571+
(ImportSearch, TraitModuleKind) |
2572+
(ImportSearch, ImplModuleKind) => {
2573+
self.session.span_err(
2574+
span,
2575+
~"cannot import from a trait \
2576+
or type implementation");
2577+
return Failed;
2578+
}
2579+
(_, _) => search_module = module_def,
2580+
}
25092581
}
25102582
}
25112583
}
@@ -2523,31 +2595,27 @@ pub impl Resolver {
25232595

25242596
index += 1;
25252597

2526-
// After the first element of the path, allow searching through
2527-
// items and imports unconditionally. This allows things like:
2528-
//
2529-
// pub mod core {
2530-
// pub use vec;
2531-
// }
2598+
// After the first element of the path, allow searching only
2599+
// through public identifiers.
25322600
//
2533-
// pub mod something_else {
2534-
// use core::vec;
2535-
// }
2536-
2537-
name_search_type = SearchItemsAndPublicImports;
2601+
// XXX: Rip this out and move it to the privacy checker.
2602+
if name_search_type == PathPublicOrPrivateSearch {
2603+
name_search_type = PathPublicOnlySearch
2604+
}
25382605
}
25392606

25402607
return Success(search_module);
25412608
}
25422609

25432610
/// Attempts to resolve the module part of an import directive or path
25442611
/// rooted at the given module.
2545-
fn resolve_module_path_for_import(@mut self,
2546-
module_: @mut Module,
2547-
module_path: &[ident],
2548-
use_lexical_scope: UseLexicalScopeFlag,
2549-
span: span)
2550-
-> ResolveResult<@mut Module> {
2612+
fn resolve_module_path(@mut self,
2613+
module_: @mut Module,
2614+
module_path: &[ident],
2615+
use_lexical_scope: UseLexicalScopeFlag,
2616+
span: span,
2617+
name_search_type: NameSearchType)
2618+
-> ResolveResult<@mut Module> {
25512619
let module_path_len = module_path.len();
25522620
assert!(module_path_len > 0);
25532621

@@ -2630,7 +2698,7 @@ pub impl Resolver {
26302698
module_path,
26312699
start_index,
26322700
span,
2633-
SearchItemsAndPublicImports)
2701+
name_search_type)
26342702
}
26352703

26362704
/// Invariant: This must only be called during main resolution, not during
@@ -2722,6 +2790,7 @@ pub impl Resolver {
27222790
}
27232791
ExternModuleKind |
27242792
TraitModuleKind |
2793+
ImplModuleKind |
27252794
AnonymousModuleKind => {
27262795
search_module = parent_module_node;
27272796
}
@@ -2741,7 +2810,7 @@ pub impl Resolver {
27412810
match self.resolve_name_in_module(search_module,
27422811
name,
27432812
namespace,
2744-
SearchItemsAndAllImports) {
2813+
PathPublicOrPrivateSearch) {
27452814
Failed => {
27462815
// Continue up the search chain.
27472816
}
@@ -2822,6 +2891,7 @@ pub impl Resolver {
28222891
NormalModuleKind => return Some(new_module),
28232892
ExternModuleKind |
28242893
TraitModuleKind |
2894+
ImplModuleKind |
28252895
AnonymousModuleKind => module_ = new_module,
28262896
}
28272897
}
@@ -2838,7 +2908,10 @@ pub impl Resolver {
28382908
-> @mut Module {
28392909
match module_.kind {
28402910
NormalModuleKind => return module_,
2841-
ExternModuleKind | TraitModuleKind | AnonymousModuleKind => {
2911+
ExternModuleKind |
2912+
TraitModuleKind |
2913+
ImplModuleKind |
2914+
AnonymousModuleKind => {
28422915
match self.get_nearest_normal_module_parent(module_) {
28432916
None => module_,
28442917
Some(new_module) => new_module
@@ -2922,8 +2995,14 @@ pub impl Resolver {
29222995

29232996
// If this is a search of all imports, we should be done with glob
29242997
// resolution at this point.
2998+
<<<<<<< HEAD
29252999
if name_search_type == SearchItemsAndAllImports {
29263000
assert_eq!(module_.glob_count, 0);
3001+
=======
3002+
if name_search_type == PathPublicOrPrivateSearch ||
3003+
name_search_type == PathPublicOnlySearch {
3004+
assert!(module_.glob_count == 0);
3005+
>>>>>>> librustc: Disallow `use` from reaching into impls or traits.
29273006
}
29283007

29293008
// Check the list of resolved imports.
@@ -2944,7 +3023,7 @@ pub impl Resolver {
29443023
}
29453024
Some(target)
29463025
if name_search_type ==
2947-
SearchItemsAndAllImports ||
3026+
PathPublicOrPrivateSearch ||
29483027
import_resolution.privacy == Public => {
29493028
debug!("(resolving name in module) resolved to \
29503029
import");
@@ -4483,10 +4562,11 @@ pub impl Resolver {
44834562
let module_path_idents = self.intern_module_part_of_path(path);
44844563

44854564
let containing_module;
4486-
match self.resolve_module_path_for_import(self.current_module,
4487-
module_path_idents,
4488-
UseLexicalScope,
4489-
path.span) {
4565+
match self.resolve_module_path(self.current_module,
4566+
module_path_idents,
4567+
UseLexicalScope,
4568+
path.span,
4569+
PathPublicOnlySearch) {
44904570
Failed => {
44914571
self.session.span_err(path.span,
44924572
fmt!("use of undeclared module `%s`",
@@ -4535,7 +4615,7 @@ pub impl Resolver {
45354615
module_path_idents,
45364616
0,
45374617
path.span,
4538-
SearchItemsAndAllImports) {
4618+
PathPublicOrPrivateSearch) {
45394619
Failed => {
45404620
self.session.span_err(path.span,
45414621
fmt!("use of undeclared module `::%s`",

0 commit comments

Comments
 (0)