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:
parent
25c54226c3
commit
7cbec5566c
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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 => {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 {
|
||||
|
25
src/test/compile-fail/issue-14221.rs
Normal file
25
src/test/compile-fail/issue-14221.rs
Normal 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() {}
|
Loading…
Reference in New Issue
Block a user