From 7cbec5566ce23701691a065866799f7057262acc Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 16 May 2014 15:44:14 -0700 Subject: [PATCH] rustc: Stop leaking enum variants into children This plugs a leak where resolve was treating enums defined in parent modules as in-scope for all children modules when resolving a pattern identifier. This eliminates the code path in resolve entirely. If this breaks any existing code, then it indicates that the variants need to be explicitly imported into the module. Closes #14221 [breaking-change] --- src/compiletest/runtest.rs | 3 +- src/libcollections/trie.rs | 2 +- src/libgreen/sched.rs | 2 +- src/librustc/driver/driver.rs | 3 +- src/librustc/middle/resolve.rs | 48 +++++++++---------------- src/librustc/middle/typeck/infer/lub.rs | 2 +- src/librustc/middle/typeck/infer/mod.rs | 1 - src/librustc/middle/typeck/infer/sub.rs | 2 +- src/libstd/io/mem.rs | 6 ++-- src/test/compile-fail/issue-14221.rs | 25 +++++++++++++ 10 files changed, 52 insertions(+), 42 deletions(-) create mode 100644 src/test/compile-fail/issue-14221.rs diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index fbbfcf94eb11d..239842dc85af8 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -9,7 +9,8 @@ // except according to those terms. use common::Config; -use common::{CompileFail, Pretty, RunFail, RunPass, DebugInfoGdb, DebugInfoLldb}; +use common::{CompileFail, Pretty, RunFail, RunPass, DebugInfoGdb}; +use common::{Codegen, DebugInfoLldb}; use errors; use header::TestProps; use header; diff --git a/src/libcollections/trie.rs b/src/libcollections/trie.rs index ce69ba00787cc..f7fed0224a2ec 100644 --- a/src/libcollections/trie.rs +++ b/src/libcollections/trie.rs @@ -634,7 +634,7 @@ impl<'a> Iterator for SetItems<'a> { #[cfg(test)] mod test_map { - use super::{TrieMap, TrieNode, Internal, External}; + use super::{TrieMap, TrieNode, Internal, External, Nothing}; use std::iter::range_step; use std::uint; diff --git a/src/libgreen/sched.rs b/src/libgreen/sched.rs index 812e998ad9d90..7faa9207bbb1f 100644 --- a/src/libgreen/sched.rs +++ b/src/libgreen/sched.rs @@ -1028,7 +1028,7 @@ mod test { use {TaskState, PoolConfig, SchedPool}; use basic; use sched::{TaskFromFriend, PinnedTask}; - use task::{GreenTask, HomeSched}; + use task::{GreenTask, HomeSched, AnySched}; fn pool() -> SchedPool { SchedPool::new(PoolConfig { diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 5f9fd7124a9e9..89395bc55bb60 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -12,7 +12,8 @@ use back::link; use driver::session::Session; use driver::{config, PpMode}; -use driver::PpmFlowGraph; // FIXME (#14221). +use driver::{PpmFlowGraph, PpmExpanded, PpmExpandedIdentified, PpmTyped}; +use driver::{PpmIdentified}; use front; use lib::llvm::{ContextRef, ModuleRef}; use metadata::common::LinkMeta; diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 471e290d9145e..48114fb514747 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -283,11 +283,6 @@ enum UseLexicalScopeFlag { UseLexicalScope } -enum SearchThroughModulesFlag { - DontSearchThroughModules, - SearchThroughModules -} - enum ModulePrefixResult { NoPrefixFound, PrefixFound(Rc, uint) @@ -2846,9 +2841,7 @@ impl<'a> Resolver<'a> { fn resolve_item_in_lexical_scope(&mut self, module_: Rc, name: Ident, - namespace: Namespace, - search_through_modules: - SearchThroughModulesFlag) + namespace: Namespace) -> ResolveResult<(Target, bool)> { debug!("(resolving item in lexical scope) resolving `{}` in \ namespace {:?} in `{}`", @@ -2921,26 +2914,19 @@ impl<'a> Resolver<'a> { return Failed; } ModuleParentLink(parent_module_node, _) => { - match search_through_modules { - DontSearchThroughModules => { - match search_module.kind.get() { - NormalModuleKind => { - // We stop the search here. - debug!("(resolving item in lexical \ - scope) unresolved module: not \ - searching through module \ - parents"); - return Failed; - } - ExternModuleKind | - TraitModuleKind | - ImplModuleKind | - AnonymousModuleKind => { - search_module = parent_module_node.upgrade().unwrap(); - } - } + match search_module.kind.get() { + NormalModuleKind => { + // We stop the search here. + debug!("(resolving item in lexical \ + scope) unresolved module: not \ + searching through module \ + parents"); + return Failed; } - SearchThroughModules => { + ExternModuleKind | + TraitModuleKind | + ImplModuleKind | + AnonymousModuleKind => { search_module = parent_module_node.upgrade().unwrap(); } } @@ -2985,7 +2971,7 @@ impl<'a> Resolver<'a> { // If this module is an anonymous module, resolve the item in the // lexical scope. Otherwise, resolve the item from the crate root. let resolve_result = self.resolve_item_in_lexical_scope( - module_, name, TypeNS, DontSearchThroughModules); + module_, name, TypeNS); match resolve_result { Success((target, _)) => { let bindings = &*target.bindings; @@ -4514,8 +4500,7 @@ impl<'a> Resolver<'a> { let module = self.current_module.clone(); match self.resolve_item_in_lexical_scope(module, name, - ValueNS, - SearchThroughModules) { + ValueNS) { Success((target, _)) => { debug!("(resolve bare identifier pattern) succeeded in \ finding {} at {:?}", @@ -4856,8 +4841,7 @@ impl<'a> Resolver<'a> { let module = self.current_module.clone(); match self.resolve_item_in_lexical_scope(module, ident, - namespace, - DontSearchThroughModules) { + namespace) { Success((target, _)) => { match (*target.bindings).def_for_namespace(namespace) { None => { diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index 174bdb4a82a3c..7ba2210a2c4fc 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - use middle::ty::{BuiltinBounds}; use middle::ty::RegionVid; use middle::ty; @@ -25,6 +24,7 @@ use collections::HashMap; use syntax::ast::{Many, Once, NodeId}; use syntax::ast::{NormalFn, UnsafeFn}; use syntax::ast::{Onceness, FnStyle}; +use syntax::ast::{MutMutable, MutImmutable}; use util::ppaux::mt_to_str; pub struct Lub<'f>(pub CombineFields<'f>); // least-upper-bound: common supertype diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index 53d1092ffd96c..30eb928a979b2 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -39,7 +39,6 @@ use middle::typeck::infer::unify::{ValsAndBindings, Root}; use middle::typeck::infer::error_reporting::ErrorReporting; use std::cell::{Cell, RefCell}; use std::rc::Rc; -use syntax::ast::{MutImmutable, MutMutable}; use syntax::ast; use syntax::codemap; use syntax::codemap::Span; diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index 437a43ed74cff..6df70d75c0f69 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -25,7 +25,7 @@ use middle::typeck::infer::{TypeTrace, Subtype}; use util::common::{indenter}; use util::ppaux::bound_region_to_str; -use syntax::ast::{Onceness, FnStyle}; +use syntax::ast::{Onceness, FnStyle, MutImmutable, MutMutable}; pub struct Sub<'f>(pub CombineFields<'f>); // "subtype", "subregion" etc diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs index 291b4f948416f..92b546d5770e6 100644 --- a/src/libstd/io/mem.rs +++ b/src/libstd/io/mem.rs @@ -23,9 +23,9 @@ use vec::Vec; fn combine(seek: SeekStyle, cur: uint, end: uint, offset: i64) -> IoResult { // compute offset as signed and clamp to prevent overflow let pos = match seek { - SeekSet => 0, - SeekEnd => end, - SeekCur => cur, + io::SeekSet => 0, + io::SeekEnd => end, + io::SeekCur => cur, } as i64; if offset + pos < 0 { diff --git a/src/test/compile-fail/issue-14221.rs b/src/test/compile-fail/issue-14221.rs new file mode 100644 index 0000000000000..c58012dc84c6e --- /dev/null +++ b/src/test/compile-fail/issue-14221.rs @@ -0,0 +1,25 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub enum E { + A, + B, +} + +pub mod b { + pub fn key(e: ::E) -> &'static str { + match e { + A => "A", + B => "B", //~ ERROR: unreachable pattern + } + } +} + +fn main() {}