Cleanup of some pattern related code
This commit is contained in:
parent
d3c94b25cb
commit
ba419a78f3
|
@ -945,52 +945,41 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||||
/// The core driver for walking a pattern; `match_mode` must be
|
/// The core driver for walking a pattern; `match_mode` must be
|
||||||
/// established up front, e.g. via `determine_pat_move_mode` (see
|
/// established up front, e.g. via `determine_pat_move_mode` (see
|
||||||
/// also `walk_irrefutable_pat` for patterns that stand alone).
|
/// also `walk_irrefutable_pat` for patterns that stand alone).
|
||||||
fn walk_pat(&mut self,
|
fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: MatchMode) {
|
||||||
cmt_discr: mc::cmt<'tcx>,
|
debug!("walk_pat cmt_discr={:?} pat={:?}", cmt_discr, pat);
|
||||||
pat: &hir::Pat,
|
|
||||||
match_mode: MatchMode) {
|
|
||||||
debug!("walk_pat cmt_discr={:?} pat={:?}", cmt_discr,
|
|
||||||
pat);
|
|
||||||
|
|
||||||
let tcx = &self.tcx();
|
let tcx = &self.tcx();
|
||||||
let mc = &self.mc;
|
let mc = &self.mc;
|
||||||
let infcx = self.mc.infcx;
|
let infcx = self.mc.infcx;
|
||||||
let delegate = &mut self.delegate;
|
let delegate = &mut self.delegate;
|
||||||
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| {
|
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| {
|
||||||
match pat.node {
|
if let PatKind::Binding(bmode, _, _) = pat.node {
|
||||||
PatKind::Binding(bmode, _, _) => {
|
debug!("binding cmt_pat={:?} pat={:?} match_mode={:?}", cmt_pat, pat, match_mode);
|
||||||
debug!("binding cmt_pat={:?} pat={:?} match_mode={:?}",
|
|
||||||
cmt_pat,
|
|
||||||
pat,
|
|
||||||
match_mode);
|
|
||||||
|
|
||||||
// pat_ty: the type of the binding being produced.
|
// pat_ty: the type of the binding being produced.
|
||||||
let pat_ty = return_if_err!(infcx.node_ty(pat.id));
|
let pat_ty = return_if_err!(infcx.node_ty(pat.id));
|
||||||
|
|
||||||
// Each match binding is effectively an assignment to the
|
// Each match binding is effectively an assignment to the
|
||||||
// binding being produced.
|
// binding being produced.
|
||||||
if let Ok(binding_cmt) = mc.cat_def(pat.id, pat.span, pat_ty,
|
if let Ok(binding_cmt) = mc.cat_def(pat.id, pat.span, pat_ty,
|
||||||
tcx.expect_def(pat.id)) {
|
tcx.expect_def(pat.id)) {
|
||||||
delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init);
|
delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init);
|
||||||
|
}
|
||||||
|
|
||||||
|
// It is also a borrow or copy/move of the value being matched.
|
||||||
|
match bmode {
|
||||||
|
hir::BindByRef(m) => {
|
||||||
|
if let ty::TyRef(&r, _) = pat_ty.sty {
|
||||||
|
let bk = ty::BorrowKind::from_mutbl(m);
|
||||||
|
delegate.borrow(pat.id, pat.span, cmt_pat, r, bk, RefBinding);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
hir::BindByValue(..) => {
|
||||||
// It is also a borrow or copy/move of the value being matched.
|
let mode = copy_or_move(infcx, &cmt_pat, PatBindingMove);
|
||||||
match bmode {
|
debug!("walk_pat binding consuming pat");
|
||||||
hir::BindByRef(m) => {
|
delegate.consume_pat(pat, cmt_pat, mode);
|
||||||
if let ty::TyRef(&r, _) = pat_ty.sty {
|
|
||||||
let bk = ty::BorrowKind::from_mutbl(m);
|
|
||||||
delegate.borrow(pat.id, pat.span, cmt_pat,
|
|
||||||
r, bk, RefBinding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hir::BindByValue(..) => {
|
|
||||||
let mode = copy_or_move(infcx, &cmt_pat, PatBindingMove);
|
|
||||||
debug!("walk_pat binding consuming pat");
|
|
||||||
delegate.consume_pat(pat, cmt_pat, mode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -999,72 +988,23 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||||
// to the above loop's visit of than the bindings that form
|
// to the above loop's visit of than the bindings that form
|
||||||
// the leaves of the pattern tree structure.
|
// the leaves of the pattern tree structure.
|
||||||
return_if_err!(mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| {
|
return_if_err!(mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| {
|
||||||
match pat.node {
|
match tcx.expect_def_or_none(pat.id) {
|
||||||
PatKind::Struct(..) | PatKind::TupleStruct(..) |
|
Some(Def::Variant(enum_did, variant_did)) => {
|
||||||
PatKind::Path(..) | PatKind::QPath(..) => {
|
let downcast_cmt = if tcx.lookup_adt_def(enum_did).is_univariant() {
|
||||||
match tcx.expect_def(pat.id) {
|
cmt_pat
|
||||||
Def::Variant(enum_did, variant_did) => {
|
} else {
|
||||||
let downcast_cmt =
|
let cmt_pat_ty = cmt_pat.ty;
|
||||||
if tcx.lookup_adt_def(enum_did).is_univariant() {
|
mc.cat_downcast(pat, cmt_pat, cmt_pat_ty, variant_did)
|
||||||
cmt_pat
|
};
|
||||||
} else {
|
|
||||||
let cmt_pat_ty = cmt_pat.ty;
|
|
||||||
mc.cat_downcast(pat, cmt_pat, cmt_pat_ty, variant_did)
|
|
||||||
};
|
|
||||||
|
|
||||||
debug!("variant downcast_cmt={:?} pat={:?}",
|
debug!("variant downcast_cmt={:?} pat={:?}", downcast_cmt, pat);
|
||||||
downcast_cmt,
|
delegate.matched_pat(pat, downcast_cmt, match_mode);
|
||||||
pat);
|
|
||||||
|
|
||||||
delegate.matched_pat(pat, downcast_cmt, match_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
Def::Struct(..) | Def::TyAlias(..) => {
|
|
||||||
// A struct (in either the value or type
|
|
||||||
// namespace; we encounter the former on
|
|
||||||
// e.g. patterns for unit structs).
|
|
||||||
|
|
||||||
debug!("struct cmt_pat={:?} pat={:?}",
|
|
||||||
cmt_pat,
|
|
||||||
pat);
|
|
||||||
|
|
||||||
delegate.matched_pat(pat, cmt_pat, match_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
Def::Const(..) | Def::AssociatedConst(..) => {
|
|
||||||
// This is a leaf (i.e. identifier binding
|
|
||||||
// or constant value to match); thus no
|
|
||||||
// `matched_pat` call.
|
|
||||||
}
|
|
||||||
|
|
||||||
def => {
|
|
||||||
// An enum type should never be in a pattern.
|
|
||||||
// Remaining cases are e.g. Def::Fn, to
|
|
||||||
// which identifiers within patterns
|
|
||||||
// should not resolve. However, we do
|
|
||||||
// encouter this when using the
|
|
||||||
// expr-use-visitor during typeck. So just
|
|
||||||
// ignore it, an error should have been
|
|
||||||
// reported.
|
|
||||||
|
|
||||||
if !tcx.sess.has_errors() {
|
|
||||||
span_bug!(pat.span,
|
|
||||||
"Pattern has unexpected def: {:?} and type {:?}",
|
|
||||||
def,
|
|
||||||
cmt_pat.ty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Some(Def::Struct(..)) | Some(Def::TyAlias(..)) | Some(Def::AssociatedTy(..)) => {
|
||||||
PatKind::Wild | PatKind::Tuple(..) | PatKind::Box(..) |
|
debug!("struct cmt_pat={:?} pat={:?}", cmt_pat, pat);
|
||||||
PatKind::Ref(..) | PatKind::Lit(..) | PatKind::Range(..) |
|
delegate.matched_pat(pat, cmt_pat, match_mode);
|
||||||
PatKind::Vec(..) | PatKind::Binding(..) => {
|
|
||||||
// Each of these cases does not
|
|
||||||
// correspond to an enum variant or struct, so we
|
|
||||||
// do not do any `matched_pat` calls for these
|
|
||||||
// cases either.
|
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1050,9 +1050,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(#19596) This is a workaround, but there should be a better way to do this
|
// FIXME(#19596) This is a workaround, but there should be a better way to do this
|
||||||
fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F)
|
fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McResult<()>
|
||||||
-> McResult<()>
|
where F : FnMut(&MemCategorizationContext<'a, 'gcx, 'tcx>, cmt<'tcx>, &hir::Pat)
|
||||||
where F : FnMut(&MemCategorizationContext<'a, 'gcx, 'tcx>, cmt<'tcx>, &hir::Pat),
|
|
||||||
{
|
{
|
||||||
// Here, `cmt` is the categorization for the value being
|
// Here, `cmt` is the categorization for the value being
|
||||||
// matched and pat is the pattern it is being matched against.
|
// matched and pat is the pattern it is being matched against.
|
||||||
|
@ -1099,21 +1098,14 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||||
// step out of sync again. So you'll see below that we always
|
// step out of sync again. So you'll see below that we always
|
||||||
// get the type of the *subpattern* and use that.
|
// get the type of the *subpattern* and use that.
|
||||||
|
|
||||||
debug!("cat_pattern: {:?} cmt={:?}",
|
debug!("cat_pattern: {:?} cmt={:?}", pat, cmt);
|
||||||
pat,
|
|
||||||
cmt);
|
|
||||||
|
|
||||||
(*op)(self, cmt.clone(), pat);
|
op(self, cmt.clone(), pat);
|
||||||
|
|
||||||
let opt_def = self.tcx().expect_def_or_none(pat.id);
|
|
||||||
if opt_def == Some(Def::Err) {
|
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: This goes up here (rather than within the PatKind::TupleStruct arm
|
// Note: This goes up here (rather than within the PatKind::TupleStruct arm
|
||||||
// alone) because struct patterns can refer to struct types or
|
// alone) because PatKind::Struct can also refer to variants.
|
||||||
// to struct variants within enums.
|
let cmt = match self.tcx().expect_def_or_none(pat.id) {
|
||||||
let cmt = match opt_def {
|
Some(Def::Err) => return Err(()),
|
||||||
Some(Def::Variant(enum_did, variant_did))
|
Some(Def::Variant(enum_did, variant_did))
|
||||||
// univariant enums do not need downcasts
|
// univariant enums do not need downcasts
|
||||||
if !self.tcx().lookup_adt_def(enum_did).is_univariant() => {
|
if !self.tcx().lookup_adt_def(enum_did).is_univariant() => {
|
||||||
|
@ -1123,68 +1115,35 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
match pat.node {
|
match pat.node {
|
||||||
PatKind::Wild => {
|
|
||||||
// _
|
|
||||||
}
|
|
||||||
|
|
||||||
PatKind::TupleStruct(_, ref subpats, ddpos) => {
|
PatKind::TupleStruct(_, ref subpats, ddpos) => {
|
||||||
match opt_def {
|
let expected_len = match self.tcx().expect_def(pat.id) {
|
||||||
Some(Def::Variant(enum_def, def_id)) => {
|
Def::Variant(enum_def, def_id) => {
|
||||||
// variant(x, y, z)
|
self.tcx().lookup_adt_def(enum_def).variant_with_id(def_id).fields.len()
|
||||||
let expected_len = self.tcx().lookup_adt_def(enum_def)
|
|
||||||
.variant_with_id(def_id).fields.len();
|
|
||||||
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
|
|
||||||
let subpat_ty = self.pat_ty(&subpat)?; // see (*2)
|
|
||||||
|
|
||||||
let subcmt =
|
|
||||||
self.cat_imm_interior(
|
|
||||||
pat, cmt.clone(), subpat_ty,
|
|
||||||
InteriorField(PositionalField(i)));
|
|
||||||
|
|
||||||
self.cat_pattern_(subcmt, &subpat, op)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Some(Def::Struct(..)) => {
|
Def::Struct(..) => {
|
||||||
let expected_len = match self.pat_ty(&pat)?.sty {
|
match self.pat_ty(&pat)?.sty {
|
||||||
ty::TyStruct(adt_def, _) => {
|
ty::TyStruct(adt_def, _) => {
|
||||||
adt_def.struct_variant().fields.len()
|
adt_def.struct_variant().fields.len()
|
||||||
}
|
}
|
||||||
ref ty => {
|
ref ty => {
|
||||||
span_bug!(pat.span, "tuple struct pattern unexpected type {:?}", ty);
|
span_bug!(pat.span, "tuple struct pattern unexpected type {:?}", ty);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
def => {
|
||||||
|
span_bug!(pat.span, "tuple struct pattern didn't resolve \
|
||||||
|
to variant or struct {:?}", def);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
|
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
|
||||||
let subpat_ty = self.pat_ty(&subpat)?; // see (*2)
|
let subpat_ty = self.pat_ty(&subpat)?; // see (*2)
|
||||||
let cmt_field =
|
let subcmt = self.cat_imm_interior(pat, cmt.clone(), subpat_ty,
|
||||||
self.cat_imm_interior(
|
InteriorField(PositionalField(i)));
|
||||||
pat, cmt.clone(), subpat_ty,
|
self.cat_pattern_(subcmt, &subpat, op)?;
|
||||||
InteriorField(PositionalField(i)));
|
|
||||||
self.cat_pattern_(cmt_field, &subpat, op)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => {
|
|
||||||
for subpat in subpats {
|
|
||||||
self.cat_pattern_(cmt.clone(), &subpat, op)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
span_bug!(
|
|
||||||
pat.span,
|
|
||||||
"enum pattern didn't resolve to enum or struct {:?}",
|
|
||||||
opt_def);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::Path(..) | PatKind::QPath(..) | PatKind::Binding(_, _, None) => {
|
|
||||||
// Lone constant, or unit variant or identifier: ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
PatKind::Binding(_, _, Some(ref subpat)) => {
|
|
||||||
self.cat_pattern_(cmt, &subpat, op)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
PatKind::Struct(_, ref field_pats, _) => {
|
PatKind::Struct(_, ref field_pats, _) => {
|
||||||
// {f1: p1, ..., fN: pN}
|
// {f1: p1, ..., fN: pN}
|
||||||
for fp in field_pats {
|
for fp in field_pats {
|
||||||
|
@ -1194,6 +1153,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PatKind::Binding(_, _, Some(ref subpat)) => {
|
||||||
|
self.cat_pattern_(cmt, &subpat, op)?;
|
||||||
|
}
|
||||||
|
|
||||||
PatKind::Tuple(ref subpats, ddpos) => {
|
PatKind::Tuple(ref subpats, ddpos) => {
|
||||||
// (p1, ..., pN)
|
// (p1, ..., pN)
|
||||||
let expected_len = match self.pat_ty(&pat)?.sty {
|
let expected_len = match self.pat_ty(&pat)?.sty {
|
||||||
|
@ -1202,10 +1165,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||||
};
|
};
|
||||||
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
|
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
|
||||||
let subpat_ty = self.pat_ty(&subpat)?; // see (*2)
|
let subpat_ty = self.pat_ty(&subpat)?; // see (*2)
|
||||||
let subcmt =
|
let subcmt = self.cat_imm_interior(pat, cmt.clone(), subpat_ty,
|
||||||
self.cat_imm_interior(
|
InteriorField(PositionalField(i)));
|
||||||
pat, cmt.clone(), subpat_ty,
|
|
||||||
InteriorField(PositionalField(i)));
|
|
||||||
self.cat_pattern_(subcmt, &subpat, op)?;
|
self.cat_pattern_(subcmt, &subpat, op)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1215,25 +1176,26 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||||
// PatKind::Ref since that information is already contained
|
// PatKind::Ref since that information is already contained
|
||||||
// in the type.
|
// in the type.
|
||||||
let subcmt = self.cat_deref(pat, cmt, 0, None)?;
|
let subcmt = self.cat_deref(pat, cmt, 0, None)?;
|
||||||
self.cat_pattern_(subcmt, &subpat, op)?;
|
self.cat_pattern_(subcmt, &subpat, op)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::Vec(ref before, ref slice, ref after) => {
|
PatKind::Vec(ref before, ref slice, ref after) => {
|
||||||
let context = InteriorOffsetKind::Pattern;
|
let context = InteriorOffsetKind::Pattern;
|
||||||
let elt_cmt = self.cat_index(pat, cmt, context)?;
|
let elt_cmt = self.cat_index(pat, cmt, context)?;
|
||||||
for before_pat in before {
|
for before_pat in before {
|
||||||
self.cat_pattern_(elt_cmt.clone(), &before_pat, op)?;
|
self.cat_pattern_(elt_cmt.clone(), &before_pat, op)?;
|
||||||
}
|
}
|
||||||
if let Some(ref slice_pat) = *slice {
|
if let Some(ref slice_pat) = *slice {
|
||||||
self.cat_pattern_(elt_cmt.clone(), &slice_pat, op)?;
|
self.cat_pattern_(elt_cmt.clone(), &slice_pat, op)?;
|
||||||
}
|
}
|
||||||
for after_pat in after {
|
for after_pat in after {
|
||||||
self.cat_pattern_(elt_cmt.clone(), &after_pat, op)?;
|
self.cat_pattern_(elt_cmt.clone(), &after_pat, op)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::Lit(_) | PatKind::Range(_, _) => {
|
PatKind::Path(..) | PatKind::QPath(..) | PatKind::Binding(_, _, None) |
|
||||||
/*always ok*/
|
PatKind::Lit(..) | PatKind::Range(..) | PatKind::Wild => {
|
||||||
|
// always ok
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -784,18 +784,14 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
|
||||||
left_ty: Ty, max_slice_length: usize) -> Vec<Constructor> {
|
left_ty: Ty, max_slice_length: usize) -> Vec<Constructor> {
|
||||||
let pat = raw_pat(p);
|
let pat = raw_pat(p);
|
||||||
match pat.node {
|
match pat.node {
|
||||||
PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) =>
|
PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::QPath(..) =>
|
||||||
match cx.tcx.expect_def(pat.id) {
|
match cx.tcx.expect_def(pat.id) {
|
||||||
Def::Const(..) | Def::AssociatedConst(..) =>
|
|
||||||
span_bug!(pat.span, "const pattern should've \
|
|
||||||
been rewritten"),
|
|
||||||
Def::Struct(..) | Def::TyAlias(..) => vec![Single],
|
|
||||||
Def::Variant(_, id) => vec![Variant(id)],
|
Def::Variant(_, id) => vec![Variant(id)],
|
||||||
def => span_bug!(pat.span, "pat_constructors: unexpected \
|
Def::Struct(..) | Def::TyAlias(..) | Def::AssociatedTy(..) => vec![Single],
|
||||||
definition {:?}", def),
|
Def::Const(..) | Def::AssociatedConst(..) =>
|
||||||
|
span_bug!(pat.span, "const pattern should've been rewritten"),
|
||||||
|
def => span_bug!(pat.span, "pat_constructors: unexpected definition {:?}", def),
|
||||||
},
|
},
|
||||||
PatKind::QPath(..) =>
|
|
||||||
span_bug!(pat.span, "const pattern should've been rewritten"),
|
|
||||||
PatKind::Lit(ref expr) =>
|
PatKind::Lit(ref expr) =>
|
||||||
vec![ConstantValue(eval_const_expr(cx.tcx, &expr))],
|
vec![ConstantValue(eval_const_expr(cx.tcx, &expr))],
|
||||||
PatKind::Range(ref lo, ref hi) =>
|
PatKind::Range(ref lo, ref hi) =>
|
||||||
|
@ -899,7 +895,7 @@ pub fn specialize<'a, 'b, 'tcx>(
|
||||||
PatKind::Binding(..) | PatKind::Wild =>
|
PatKind::Binding(..) | PatKind::Wild =>
|
||||||
Some(vec![dummy_pat; arity]),
|
Some(vec![dummy_pat; arity]),
|
||||||
|
|
||||||
PatKind::Path(..) => {
|
PatKind::Path(..) | PatKind::QPath(..) => {
|
||||||
match cx.tcx.expect_def(pat_id) {
|
match cx.tcx.expect_def(pat_id) {
|
||||||
Def::Const(..) | Def::AssociatedConst(..) =>
|
Def::Const(..) | Def::AssociatedConst(..) =>
|
||||||
span_bug!(pat_span, "const pattern should've \
|
span_bug!(pat_span, "const pattern should've \
|
||||||
|
@ -934,10 +930,6 @@ pub fn specialize<'a, 'b, 'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::QPath(_, _) => {
|
|
||||||
span_bug!(pat_span, "const pattern should've been rewritten")
|
|
||||||
}
|
|
||||||
|
|
||||||
PatKind::Struct(_, ref pattern_fields, _) => {
|
PatKind::Struct(_, ref pattern_fields, _) => {
|
||||||
let adt = cx.tcx.node_id_to_type(pat_id).ty_adt_def().unwrap();
|
let adt = cx.tcx.node_id_to_type(pat_id).ty_adt_def().unwrap();
|
||||||
let variant = constructor.variant_for_adt(adt);
|
let variant = constructor.variant_for_adt(adt);
|
||||||
|
|
|
@ -13,7 +13,7 @@ use hair::cx::Cx;
|
||||||
use rustc_data_structures::indexed_vec::Idx;
|
use rustc_data_structures::indexed_vec::Idx;
|
||||||
use rustc_const_eval as const_eval;
|
use rustc_const_eval as const_eval;
|
||||||
use rustc::hir::def::Def;
|
use rustc::hir::def::Def;
|
||||||
use rustc::hir::pat_util::{EnumerateAndAdjustIterator, pat_is_resolved_const};
|
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
use rustc::mir::repr::*;
|
use rustc::mir::repr::*;
|
||||||
use rustc::hir::{self, PatKind};
|
use rustc::hir::{self, PatKind};
|
||||||
|
@ -76,9 +76,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
|
||||||
PatternKind::Range { lo: lo, hi: hi }
|
PatternKind::Range { lo: lo, hi: hi }
|
||||||
},
|
},
|
||||||
|
|
||||||
PatKind::Path(..) | PatKind::QPath(..)
|
PatKind::Path(..) | PatKind::QPath(..) => {
|
||||||
if pat_is_resolved_const(&self.cx.tcx.def_map.borrow(), pat) =>
|
|
||||||
{
|
|
||||||
match self.cx.tcx.expect_def(pat.id) {
|
match self.cx.tcx.expect_def(pat.id) {
|
||||||
Def::Const(def_id) | Def::AssociatedConst(def_id) => {
|
Def::Const(def_id) | Def::AssociatedConst(def_id) => {
|
||||||
let tcx = self.cx.tcx.global_tcx();
|
let tcx = self.cx.tcx.global_tcx();
|
||||||
|
@ -104,11 +102,9 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def =>
|
_ => {
|
||||||
span_bug!(
|
self.variant_or_leaf(pat, vec![])
|
||||||
pat.span,
|
}
|
||||||
"def not a constant: {:?}",
|
|
||||||
def),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,10 +195,6 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::Path(..) => {
|
|
||||||
self.variant_or_leaf(pat, vec![])
|
|
||||||
}
|
|
||||||
|
|
||||||
PatKind::TupleStruct(_, ref subpatterns, ddpos) => {
|
PatKind::TupleStruct(_, ref subpatterns, ddpos) => {
|
||||||
let pat_ty = self.cx.tcx.node_id_to_type(pat.id);
|
let pat_ty = self.cx.tcx.node_id_to_type(pat.id);
|
||||||
let adt_def = match pat_ty.sty {
|
let adt_def = match pat_ty.sty {
|
||||||
|
@ -253,10 +245,6 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
|
||||||
|
|
||||||
self.variant_or_leaf(pat, subpatterns)
|
self.variant_or_leaf(pat, subpatterns)
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::QPath(..) => {
|
|
||||||
span_bug!(pat.span, "unexpanded macro or bad constant etc");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Pattern {
|
Pattern {
|
||||||
|
@ -325,7 +313,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Def::Struct(..) | Def::TyAlias(..) => {
|
Def::Struct(..) | Def::TyAlias(..) | Def::AssociatedTy(..) => {
|
||||||
PatternKind::Leaf { subpatterns: subpatterns }
|
PatternKind::Leaf { subpatterns: subpatterns }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -436,7 +436,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::ExprPath(..) => {
|
hir::ExprPath(..) => {
|
||||||
|
|
||||||
if let Def::Struct(..) = self.tcx.expect_def(expr.id) {
|
if let Def::Struct(..) = self.tcx.expect_def(expr.id) {
|
||||||
let expr_ty = self.tcx.expr_ty(expr);
|
let expr_ty = self.tcx.expr_ty(expr);
|
||||||
let def = match expr_ty.sty {
|
let def = match expr_ty.sty {
|
||||||
|
|
Loading…
Reference in New Issue