diff options
| author | Andrew Cann <shum@canndrew.org> | 2016-12-29 17:08:33 +0800 |
|---|---|---|
| committer | Andrew Cann <shum@canndrew.org> | 2017-01-03 15:54:23 +0800 |
| commit | 9f83e962de29dec0eea7c8ae4ac403bbc6ad1f16 (patch) | |
| tree | 925f86218c49bd596ed7229100570ce050c27273 | |
| parent | 4136ba072e1b8ff5c06de2c3dc4b72773ae1b3e5 (diff) | |
| download | rust-9f83e962de29dec0eea7c8ae4ac403bbc6ad1f16.tar.gz rust-9f83e962de29dec0eea7c8ae4ac403bbc6ad1f16.zip | |
Fix build after rebase.
Mostly just rename stuff. Visibility checks use DefIds rather than NodeIds now.
| -rw-r--r-- | src/librustc/ty/context.rs | 4 | ||||
| -rw-r--r-- | src/librustc/ty/inhabitedness.rs | 174 | ||||
| -rw-r--r-- | src/librustc/ty/mod.rs | 25 | ||||
| -rw-r--r-- | src/librustc/ty/sty.rs | 10 | ||||
| -rw-r--r-- | src/librustc_const_eval/_match.rs | 28 | ||||
| -rw-r--r-- | src/librustc_const_eval/check_match.rs | 6 |
6 files changed, 129 insertions, 118 deletions
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 6c7946a528e..6450ddaa532 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -33,7 +33,7 @@ use ty::{BareFnTy, InferTy, ParamTy, ProjectionTy, ExistentialPredicate}; use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid}; use ty::TypeVariants::*; use ty::layout::{Layout, TargetDataLayout}; -use ty::inhabitedness::NodeForrest; +use ty::inhabitedness::DefIdForrest; use ty::maps; use util::common::MemoizationMap; use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet}; @@ -460,7 +460,7 @@ pub struct GlobalCtxt<'tcx> { // FIXME dep tracking -- should be harmless enough pub normalized_cache: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>, - pub inhabitedness_cache: RefCell<FxHashMap<Ty<'tcx>, NodeForrest>>, + pub inhabitedness_cache: RefCell<FxHashMap<Ty<'tcx>, DefIdForrest>>, pub lang_items: middle::lang_items::LanguageItems, diff --git a/src/librustc/ty/inhabitedness.rs b/src/librustc/ty/inhabitedness.rs index 5acffca2679..dc21e848711 100644 --- a/src/librustc/ty/inhabitedness.rs +++ b/src/librustc/ty/inhabitedness.rs @@ -10,118 +10,120 @@ use std::mem; use rustc_data_structures::small_vec::SmallVec; -use syntax::ast::{CRATE_NODE_ID, NodeId}; +use syntax::ast::CRATE_NODE_ID; use util::nodemap::FxHashSet; use ty::context::TyCtxt; use ty::{AdtDef, VariantDef, FieldDef, TyS}; use ty::{DefId, Substs}; -use ty::{AdtKind, Visibility, NodeIdTree}; +use ty::{AdtKind, Visibility, DefIdTree}; use ty::TypeVariants::*; -/// Represents a set of nodes closed under the ancestor relation. That is, if a -/// node is in this set then so are all its descendants. +/// Represents a set of DefIds closed under the ancestor relation. That is, if +/// a DefId is in this set then so are all its descendants. #[derive(Clone)] -pub struct NodeForrest { - /// The minimal set of nodes required to represent the whole set. - /// If A and B are nodes in the NodeForrest, and A is a desecendant - /// of B, then only B will be in root_nodes. +pub struct DefIdForrest { + /// The minimal set of DefIds required to represent the whole set. + /// If A and B are DefIds in the DefIdForrest, and A is a desecendant + /// of B, then only B will be in root_ids. /// We use a SmallVec here because (for its use in this module) its rare - /// that this will contain more than one or two nodes. - root_nodes: SmallVec<[NodeId; 1]>, + /// that this will contain even two ids. + root_ids: SmallVec<[DefId; 1]>, } -impl<'a, 'gcx, 'tcx> NodeForrest { - /// Create an empty set. - pub fn empty() -> NodeForrest { - NodeForrest { - root_nodes: SmallVec::new(), +impl<'a, 'gcx, 'tcx> DefIdForrest { + /// Create an empty forrest. + pub fn empty() -> DefIdForrest { + DefIdForrest { + root_ids: SmallVec::new(), } } - /// Create a set containing every node. + /// Create a forrest consisting of a single tree representing the entire + /// crate. #[inline] - pub fn full() -> NodeForrest { - NodeForrest::from_node(CRATE_NODE_ID) + pub fn full(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> DefIdForrest { + let crate_id = tcx.map.local_def_id(CRATE_NODE_ID); + DefIdForrest::from_id(crate_id) } - /// Create a set containing a node and all its descendants. - pub fn from_node(node: NodeId) -> NodeForrest { - let mut root_nodes = SmallVec::new(); - root_nodes.push(node); - NodeForrest { - root_nodes: root_nodes, + /// Create a forrest containing a DefId and all its descendants. + pub fn from_id(id: DefId) -> DefIdForrest { + let mut root_ids = SmallVec::new(); + root_ids.push(id); + DefIdForrest { + root_ids: root_ids, } } - /// Test whether the set is empty. + /// Test whether the forrest is empty. pub fn is_empty(&self) -> bool { - self.root_nodes.is_empty() + self.root_ids.is_empty() } - /// Test whether the set conains a node. + /// Test whether the forrest conains a given DefId. pub fn contains(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, - node: NodeId) -> bool + id: DefId) -> bool { - for root_node in self.root_nodes.iter() { - if tcx.map.is_descendant_of(node, *root_node) { + for root_id in self.root_ids.iter() { + if tcx.is_descendant_of(id, *root_id) { return true; } } false } - /// Calculate the intersection of a collection of sets. + /// Calculate the intersection of a collection of forrests. pub fn intersection<I>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - iter: I) -> NodeForrest - where I: IntoIterator<Item=NodeForrest> + iter: I) -> DefIdForrest + where I: IntoIterator<Item=DefIdForrest> { - let mut ret = NodeForrest::full(); + let mut ret = DefIdForrest::full(tcx); let mut next_ret = SmallVec::new(); - let mut old_ret: SmallVec<[NodeId; 1]> = SmallVec::new(); - for next_set in iter { - for node in ret.root_nodes.drain(..) { - if next_set.contains(tcx, node) { - next_ret.push(node); + let mut old_ret: SmallVec<[DefId; 1]> = SmallVec::new(); + for next_forrest in iter { + for id in ret.root_ids.drain(..) { + if next_forrest.contains(tcx, id) { + next_ret.push(id); } else { - old_ret.push(node); + old_ret.push(id); } } - ret.root_nodes.extend(old_ret.drain(..)); + ret.root_ids.extend(old_ret.drain(..)); - for node in next_set.root_nodes { - if ret.contains(tcx, node) { - next_ret.push(node); + for id in next_forrest.root_ids { + if ret.contains(tcx, id) { + next_ret.push(id); } } - mem::swap(&mut next_ret, &mut ret.root_nodes); + mem::swap(&mut next_ret, &mut ret.root_ids); next_ret.drain(..); } ret } - /// Calculate the union of a collection of sets. + /// Calculate the union of a collection of forrests. pub fn union<I>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - iter: I) -> NodeForrest - where I: IntoIterator<Item=NodeForrest> + iter: I) -> DefIdForrest + where I: IntoIterator<Item=DefIdForrest> { - let mut ret = NodeForrest::empty(); + let mut ret = DefIdForrest::empty(); let mut next_ret = SmallVec::new(); - for next_set in iter { - for node in ret.root_nodes.drain(..) { - if !next_set.contains(tcx, node) { - next_ret.push(node); + for next_forrest in iter { + for id in ret.root_ids.drain(..) { + if !next_forrest.contains(tcx, id) { + next_ret.push(id); } } - for node in next_set.root_nodes { - if !next_ret.contains(&node) { - next_ret.push(node); + for id in next_forrest.root_ids { + if !next_ret.contains(&id) { + next_ret.push(id); } } - mem::swap(&mut next_ret, &mut ret.root_nodes); + mem::swap(&mut next_ret, &mut ret.root_ids); next_ret.drain(..); } ret @@ -129,18 +131,18 @@ impl<'a, 'gcx, 'tcx> NodeForrest { } impl<'a, 'gcx, 'tcx> AdtDef { - /// Calculate the set of nodes from which this adt is visibly uninhabited. + /// Calculate the forrest of DefIds from which this adt is visibly uninhabited. pub fn uninhabited_from( &self, visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>, tcx: TyCtxt<'a, 'gcx, 'tcx>, - substs: &'tcx Substs<'tcx>) -> NodeForrest + substs: &'tcx Substs<'tcx>) -> DefIdForrest { if !visited.insert((self.did, substs)) { - return NodeForrest::empty(); + return DefIdForrest::empty(); } - let ret = NodeForrest::intersection(tcx, self.variants.iter().map(|v| { + let ret = DefIdForrest::intersection(tcx, self.variants.iter().map(|v| { v.uninhabited_from(visited, tcx, substs, self.adt_kind()) })); visited.remove(&(self.did, substs)); @@ -149,27 +151,27 @@ impl<'a, 'gcx, 'tcx> AdtDef { } impl<'a, 'gcx, 'tcx> VariantDef { - /// Calculate the set of nodes from which this variant is visibly uninhabited. + /// Calculate the forrest of DefIds from which this variant is visibly uninhabited. pub fn uninhabited_from( &self, visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &'tcx Substs<'tcx>, - adt_kind: AdtKind) -> NodeForrest + adt_kind: AdtKind) -> DefIdForrest { match adt_kind { AdtKind::Union => { - NodeForrest::intersection(tcx, self.fields.iter().map(|f| { + DefIdForrest::intersection(tcx, self.fields.iter().map(|f| { f.uninhabited_from(visited, tcx, substs, false) })) }, AdtKind::Struct => { - NodeForrest::union(tcx, self.fields.iter().map(|f| { + DefIdForrest::union(tcx, self.fields.iter().map(|f| { f.uninhabited_from(visited, tcx, substs, false) })) }, AdtKind::Enum => { - NodeForrest::union(tcx, self.fields.iter().map(|f| { + DefIdForrest::union(tcx, self.fields.iter().map(|f| { f.uninhabited_from(visited, tcx, substs, true) })) }, @@ -178,24 +180,24 @@ impl<'a, 'gcx, 'tcx> VariantDef { } impl<'a, 'gcx, 'tcx> FieldDef { - /// Calculate the set of nodes from which this field is visibly uninhabited. + /// Calculate the forrest of DefIds from which this field is visibly uninhabited. pub fn uninhabited_from( &self, visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &'tcx Substs<'tcx>, - is_enum: bool) -> NodeForrest + is_enum: bool) -> DefIdForrest { let mut data_uninhabitedness = move || self.ty(tcx, substs).uninhabited_from(visited, tcx); if is_enum { data_uninhabitedness() } else { match self.vis { - Visibility::PrivateExternal => NodeForrest::empty(), + Visibility::Invisible => DefIdForrest::empty(), Visibility::Restricted(from) => { - let node_set = NodeForrest::from_node(from); - let iter = Some(node_set).into_iter().chain(Some(data_uninhabitedness())); - NodeForrest::intersection(tcx, iter) + let forrest = DefIdForrest::from_id(from); + let iter = Some(forrest).into_iter().chain(Some(data_uninhabitedness())); + DefIdForrest::intersection(tcx, iter) }, Visibility::Public => data_uninhabitedness(), } @@ -204,28 +206,28 @@ impl<'a, 'gcx, 'tcx> FieldDef { } impl<'a, 'gcx, 'tcx> TyS<'tcx> { - /// Calculate the set of nodes from which this type is visibly uninhabited. + /// Calculate the forrest of DefIds from which this type is visibly uninhabited. pub fn uninhabited_from( &self, visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>, - tcx: TyCtxt<'a, 'gcx, 'tcx>) -> NodeForrest + tcx: TyCtxt<'a, 'gcx, 'tcx>) -> DefIdForrest { match tcx.lift_to_global(&self) { Some(global_ty) => { { let cache = tcx.inhabitedness_cache.borrow(); - if let Some(closed_node_set) = cache.get(&global_ty) { - return closed_node_set.clone(); + if let Some(forrest) = cache.get(&global_ty) { + return forrest.clone(); } } - let node_set = global_ty.uninhabited_from_inner(visited, tcx); + let forrest = global_ty.uninhabited_from_inner(visited, tcx); let mut cache = tcx.inhabitedness_cache.borrow_mut(); - cache.insert(global_ty, node_set.clone()); - node_set + cache.insert(global_ty, forrest.clone()); + forrest }, None => { - let node_set = self.uninhabited_from_inner(visited, tcx); - node_set + let forrest = self.uninhabited_from_inner(visited, tcx); + forrest }, } } @@ -233,29 +235,29 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { fn uninhabited_from_inner( &self, visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>, - tcx: TyCtxt<'a, 'gcx, 'tcx>) -> NodeForrest + tcx: TyCtxt<'a, 'gcx, 'tcx>) -> DefIdForrest { match self.sty { TyAdt(def, substs) => { def.uninhabited_from(visited, tcx, substs) }, - TyNever => NodeForrest::full(), + TyNever => DefIdForrest::full(tcx), TyTuple(ref tys) => { - NodeForrest::union(tcx, tys.iter().map(|ty| { + DefIdForrest::union(tcx, tys.iter().map(|ty| { ty.uninhabited_from(visited, tcx) })) }, TyArray(ty, len) => { if len == 0 { - NodeForrest::empty() + DefIdForrest::empty() } else { ty.uninhabited_from(visited, tcx) } } TyRef(_, ref tm) => tm.ty.uninhabited_from(visited, tcx), - _ => NodeForrest::empty(), + _ => DefIdForrest::empty(), } } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 7cfc0f74214..fa62e893a28 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -227,6 +227,20 @@ pub enum Visibility { pub trait DefIdTree: Copy { fn parent(self, id: DefId) -> Option<DefId>; + + fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool { + if descendant.krate != ancestor.krate { + return false; + } + + while descendant != ancestor { + match self.parent(descendant) { + Some(parent) => descendant = parent, + None => return false, + } + } + true + } } impl<'a, 'gcx, 'tcx> DefIdTree for TyCtxt<'a, 'gcx, 'tcx> { @@ -253,7 +267,7 @@ impl Visibility { } /// Returns true if an item with this visibility is accessible from the given block. - pub fn is_accessible_from<T: DefIdTree>(self, mut module: DefId, tree: T) -> bool { + pub fn is_accessible_from<T: DefIdTree>(self, module: DefId, tree: T) -> bool { let restriction = match self { // Public items are visible everywhere. Visibility::Public => return true, @@ -264,14 +278,7 @@ impl Visibility { Visibility::Restricted(module) => module, }; - while module != restriction { - match tree.parent(module) { - Some(parent) => module = parent, - None => return false, - } - } - - true + tree.is_descendant_of(module, restriction) } /// Returns true if this visibility is at least as accessible as the given visibility diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 340b7415f5c..92c616b8c71 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -22,7 +22,7 @@ use std::fmt; use std::iter; use std::cmp::Ordering; use syntax::abi; -use syntax::ast::{self, Name, NodeId}; +use syntax::ast::{self, Name}; use syntax::symbol::{keywords, InternedString}; use util::nodemap::FxHashSet; @@ -979,11 +979,11 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } } - /// Checks whether a type is visibly uninhabited from a particular node. - pub fn is_uninhabited_from(&self, block: NodeId, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool { + /// Checks whether a type is visibly uninhabited from a particular module. + pub fn is_uninhabited_from(&self, module: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool { let mut visited = FxHashSet::default(); - let node_set = self.uninhabited_from(&mut visited, tcx); - node_set.contains(tcx, block) + let forrest = self.uninhabited_from(&mut visited, tcx); + forrest.contains(tcx, module) } /// Checks whether a type is uninhabited. diff --git a/src/librustc_const_eval/_match.rs b/src/librustc_const_eval/_match.rs index ea01857745e..f1bd659bd2d 100644 --- a/src/librustc_const_eval/_match.rs +++ b/src/librustc_const_eval/_match.rs @@ -29,7 +29,8 @@ use rustc::ty::{self, AdtKind, Ty, TyCtxt, TypeFoldable}; use rustc::mir::Field; use rustc::util::common::ErrorReported; -use syntax::ast::NodeId; +use syntax::ast::DUMMY_NODE_ID; +use syntax::ptr::P; use syntax_pos::{Span, DUMMY_SP}; use arena::TypedArena; @@ -145,14 +146,13 @@ impl<'a, 'tcx> FromIterator<Vec<&'a Pattern<'tcx>>> for Matrix<'a, 'tcx> { //NOTE: appears to be the only place other then InferCtxt to contain a ParamEnv pub struct MatchCheckCtxt<'a, 'tcx: 'a> { pub tcx: TyCtxt<'a, 'tcx, 'tcx>, - /// (roughly) where in the code the match occurs. This is necessary for + /// The module in which the match occurs. This is necessary for /// checking inhabited-ness of types because whether a type is (visibly) /// inhabited can depend on whether it was defined in the current module or - /// not. eg. - /// struct Foo { _private: ! } - /// can not be seen to be empty outside it's module and should not - /// be matchable with an empty match statement. - pub node: NodeId, + /// not. eg. `struct Foo { _private: ! }` cannot be seen to be empty + /// outside it's module and should not be matchable with an empty match + /// statement. + pub module: DefId, pub pattern_arena: &'a TypedArena<Pattern<'tcx>>, pub byte_array_map: FxHashMap<*const Pattern<'tcx>, Vec<&'a Pattern<'tcx>>>, } @@ -160,7 +160,7 @@ pub struct MatchCheckCtxt<'a, 'tcx: 'a> { impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { pub fn create_and_enter<F, R>( tcx: TyCtxt<'a, 'tcx, 'tcx>, - node: NodeId, + module: DefId, f: F) -> R where F: for<'b> FnOnce(MatchCheckCtxt<'b, 'tcx>) -> R { @@ -168,7 +168,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { f(MatchCheckCtxt { tcx: tcx, - node: node, + module: module, pattern_arena: &pattern_arena, byte_array_map: FxHashMap(), }) @@ -379,14 +379,14 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, ty::TyBool => [true, false].iter().map(|b| ConstantValue(ConstVal::Bool(*b))).collect(), ty::TySlice(ref sub_ty) => { - if sub_ty.is_uninhabited_from(cx.node, cx.tcx) { + if sub_ty.is_uninhabited_from(cx.module, cx.tcx) { vec![Slice(0)] } else { (0..pcx.max_slice_length+1).map(|length| Slice(length)).collect() } } ty::TyArray(ref sub_ty, length) => { - if length == 0 || !sub_ty.is_uninhabited_from(cx.node, cx.tcx) { + if length == 0 || !sub_ty.is_uninhabited_from(cx.module, cx.tcx) { vec![Slice(length)] } else { vec![] @@ -395,10 +395,10 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, ty::TyAdt(def, substs) if def.is_enum() && def.variants.len() != 1 => { def.variants.iter().filter_map(|v| { let mut visited = FxHashSet::default(); - let node_set = v.uninhabited_from(&mut visited, + let forrest = v.uninhabited_from(&mut visited, cx.tcx, substs, AdtKind::Enum); - if node_set.contains(cx.tcx, cx.node) { + if forrest.contains(cx.tcx, cx.module) { None } else { Some(Variant(v.did)) @@ -406,7 +406,7 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, }).collect() } _ => { - if pcx.ty.is_uninhabited_from(cx.node, cx.tcx) { + if pcx.ty.is_uninhabited_from(cx.module, cx.tcx) { vec![] } else { vec![Single] diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 4b79cd7695e..824f1e3c975 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -150,7 +150,8 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { } } - MatchCheckCtxt::create_and_enter(self.tcx, scrut.id, |ref mut cx| { + let module = self.tcx.map.local_def_id(self.tcx.map.get_module_parent(scrut.id)); + MatchCheckCtxt::create_and_enter(self.tcx, module, |ref mut cx| { let mut have_errors = false; let inlined_arms : Vec<(Vec<_>, _)> = arms.iter().map(|arm| ( @@ -192,7 +193,8 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { "local binding" }; - MatchCheckCtxt::create_and_enter(self.tcx, pat.id, |ref mut cx| { + let module = self.tcx.map.local_def_id(self.tcx.map.get_module_parent(pat.id)); + MatchCheckCtxt::create_and_enter(self.tcx, module, |ref mut cx| { let mut patcx = PatternContext::new(self.tcx); let pattern = patcx.lower_pattern(pat); let pattern_ty = pattern.ty; |
