Fix build after rebase.
Mostly just rename stuff. Visibility checks use DefIds rather than NodeIds now.
This commit is contained in:
parent
4136ba072e
commit
9f83e962de
6 changed files with 129 additions and 118 deletions
|
|
@ -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,
|
||||
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue