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]
This commit is contained in:
Alex Crichton 2014-05-16 15:44:14 -07:00
parent 25c54226c3
commit 7cbec5566c
10 changed files with 52 additions and 42 deletions

View File

@ -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;

View File

@ -634,7 +634,7 @@ impl<'a> Iterator<uint> 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;

View File

@ -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 {

View File

@ -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;

View File

@ -283,11 +283,6 @@ enum UseLexicalScopeFlag {
UseLexicalScope
}
enum SearchThroughModulesFlag {
DontSearchThroughModules,
SearchThroughModules
}
enum ModulePrefixResult {
NoPrefixFound,
PrefixFound(Rc<Module>, uint)
@ -2846,9 +2841,7 @@ impl<'a> Resolver<'a> {
fn resolve_item_in_lexical_scope(&mut self,
module_: Rc<Module>,
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 => {

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -23,9 +23,9 @@ use vec::Vec;
fn combine(seek: SeekStyle, cur: uint, end: uint, offset: i64) -> IoResult<u64> {
// 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 {

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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() {}