use crate::hair::util::UserAnnotatedTyHelpers;
use crate::hair::constant::*;
-use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability};
+use rustc::mir::{Field, BorrowKind, Mutability};
use rustc::mir::{UserTypeProjection};
-use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend};
+use rustc::mir::interpret::{GlobalId, ConstValue, sign_extend, AllocId, Pointer};
use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, UserType, DefIdTree};
use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations};
use rustc::ty::subst::{SubstsRef, Kind};
-use rustc::ty::layout::VariantIdx;
+use rustc::ty::layout::{VariantIdx, Size};
use rustc::hir::{self, PatKind, RangeEnd};
-use rustc::hir::def::{CtorOf, Def, CtorKind};
+use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind};
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
use rustc_data_structures::indexed_vec::Idx;
use std::fmt;
use syntax::ast;
use syntax::ptr::P;
+use syntax::symbol::sym;
use syntax_pos::Span;
#[derive(Clone, Debug)]
},
Constant {
- value: ty::Const<'tcx>,
+ value: &'tcx ty::Const<'tcx>,
},
Range(PatternRange<'tcx>),
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct PatternRange<'tcx> {
- pub lo: ty::Const<'tcx>,
- pub hi: ty::Const<'tcx>,
+ pub lo: &'tcx ty::Const<'tcx>,
+ pub hi: &'tcx ty::Const<'tcx>,
pub ty: Ty<'tcx>,
pub end: RangeEnd,
}
write!(f, "{}", subpattern)
}
PatternKind::Constant { value } => {
- fmt_const_val(f, value)
+ write!(f, "{}", value)
}
PatternKind::Range(PatternRange { lo, hi, ty: _, end }) => {
- fmt_const_val(f, lo)?;
+ write!(f, "{}", lo)?;
match end {
RangeEnd::Included => write!(f, "..=")?,
RangeEnd::Excluded => write!(f, "..")?,
}
- fmt_const_val(f, hi)
+ write!(f, "{}", hi)
}
PatternKind::Slice { ref prefix, ref slice, ref suffix } |
PatternKind::Array { ref prefix, ref slice, ref suffix } => {
}
PatKind::TupleStruct(ref qpath, ref subpatterns, ddpos) => {
- let def = self.tables.qpath_def(qpath, pat.hir_id);
+ let res = self.tables.qpath_res(qpath, pat.hir_id);
let adt_def = match ty.sty {
ty::Adt(adt_def, _) => adt_def,
ty::Error => { // Avoid ICE (#50585)
"tuple struct pattern not applied to an ADT {:?}",
ty),
};
- let variant_def = adt_def.variant_of_def(def);
+ let variant_def = adt_def.variant_of_res(res);
let subpatterns =
subpatterns.iter()
})
.collect();
- self.lower_variant_or_leaf(def, pat.hir_id, pat.span, ty, subpatterns)
+ self.lower_variant_or_leaf(res, pat.hir_id, pat.span, ty, subpatterns)
}
PatKind::Struct(ref qpath, ref fields, _) => {
- let def = self.tables.qpath_def(qpath, pat.hir_id);
+ let res = self.tables.qpath_res(qpath, pat.hir_id);
let subpatterns =
fields.iter()
.map(|field| {
})
.collect();
- self.lower_variant_or_leaf(def, pat.hir_id, pat.span, ty, subpatterns)
+ self.lower_variant_or_leaf(res, pat.hir_id, pat.span, ty, subpatterns)
}
};
fn lower_variant_or_leaf(
&mut self,
- def: Def,
+ res: Res,
hir_id: hir::HirId,
span: Span,
ty: Ty<'tcx>,
subpatterns: Vec<FieldPattern<'tcx>>,
) -> PatternKind<'tcx> {
- let def = match def {
- Def::Ctor(variant_ctor_id, CtorOf::Variant, ..) => {
+ let res = match res {
+ Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => {
let variant_id = self.tcx.parent(variant_ctor_id).unwrap();
- Def::Variant(variant_id)
+ Res::Def(DefKind::Variant, variant_id)
},
- def => def,
+ res => res,
};
- let mut kind = match def {
- Def::Variant(variant_id) => {
+ let mut kind = match res {
+ Res::Def(DefKind::Variant, variant_id) => {
let enum_id = self.tcx.parent(variant_id).unwrap();
let adt_def = self.tcx.adt_def(enum_id);
if adt_def.is_enum() {
}
}
- Def::Struct(..) | Def::Ctor(_, CtorOf::Struct, ..) | Def::Union(..) |
- Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) | Def::SelfCtor(..) => {
+ Res::Def(DefKind::Struct, _)
+ | Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _)
+ | Res::Def(DefKind::Union, _)
+ | Res::Def(DefKind::TyAlias, _)
+ | Res::Def(DefKind::AssociatedTy, _)
+ | Res::SelfTy(..)
+ | Res::SelfCtor(..) => {
PatternKind::Leaf { subpatterns }
}
span: Span)
-> Pattern<'tcx> {
let ty = self.tables.node_type(id);
- let def = self.tables.qpath_def(qpath, id);
- let is_associated_const = match def {
- Def::AssociatedConst(_) => true,
+ let res = self.tables.qpath_res(qpath, id);
+ let is_associated_const = match res {
+ Res::Def(DefKind::AssociatedConst, _) => true,
_ => false,
};
- let kind = match def {
- Def::Const(def_id) | Def::AssociatedConst(def_id) => {
+ let kind = match res {
+ Res::Def(DefKind::Const, def_id) | Res::Def(DefKind::AssociatedConst, def_id) => {
let substs = self.tables.node_substs(id);
match ty::Instance::resolve(
self.tcx,
},
}
}
- _ => self.lower_variant_or_leaf(def, id, span, ty, vec![]),
+ _ => self.lower_variant_or_leaf(res, id, span, ty, vec![]),
};
Pattern {
fn const_to_pat(
&self,
instance: ty::Instance<'tcx>,
- cv: ty::Const<'tcx>,
+ cv: &'tcx ty::Const<'tcx>,
id: hir::HirId,
span: Span,
) -> Pattern<'tcx> {
self.tcx.sess.span_err(span, "cannot use unions in constant patterns");
PatternKind::Wild
}
- ty::Adt(adt_def, _) if !self.tcx.has_attr(adt_def.did, "structural_match") => {
+ ty::Adt(adt_def, _) if !self.tcx.has_attr(adt_def.did, sym::structural_match) => {
let path = self.tcx.def_path_str(adt_def.did);
let msg = format!(
"to use a constant of type `{}` in a pattern, \
PatternKind::Wild
}
ty::Ref(_, ty::TyS { sty: ty::Adt(adt_def, _), .. }, _)
- if !self.tcx.has_attr(adt_def.did, "structural_match") => {
+ if !self.tcx.has_attr(adt_def.did, sym::structural_match) => {
// HACK(estebank): Side-step ICE #53708, but anything other than erroring here
// would be wrong. Returnging `PatternKind::Wild` is not technically correct.
let path = self.tcx.def_path_str(adt_def.did);
PatternKind::Constant {
value
} => PatternKind::Constant {
- value: value.fold_with(folder)
+ value,
},
PatternKind::Range(PatternRange {
lo,
ty,
end,
}) => PatternKind::Range(PatternRange {
- lo: lo.fold_with(folder),
- hi: hi.fold_with(folder),
+ lo,
+ hi,
ty: ty.fold_with(folder),
end,
}),
pub fn compare_const_vals<'a, 'gcx, 'tcx>(
tcx: TyCtxt<'a, 'gcx, 'tcx>,
- a: ty::Const<'tcx>,
- b: ty::Const<'tcx>,
+ a: &'tcx ty::Const<'tcx>,
+ b: &'tcx ty::Const<'tcx>,
ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
) -> Option<Ordering> {
trace!("compare_const_vals: {:?}, {:?}", a, b);
if let ty::Str = ty.value.sty {
match (a.val, b.val) {
(
- ConstValue::Slice(
- Scalar::Ptr(ptr_a),
- len_a,
- ),
- ConstValue::Slice(
- Scalar::Ptr(ptr_b),
- len_b,
- ),
- ) if ptr_a.offset.bytes() == 0 && ptr_b.offset.bytes() == 0 => {
- if len_a == len_b {
- let map = tcx.alloc_map.lock();
- let alloc_a = map.unwrap_memory(ptr_a.alloc_id);
- let alloc_b = map.unwrap_memory(ptr_b.alloc_id);
- if alloc_a.bytes.len() as u64 == len_a {
- return from_bool(alloc_a == alloc_b);
- }
+ ConstValue::Slice { data: alloc_a, start: offset_a, end: end_a },
+ ConstValue::Slice { data: alloc_b, start: offset_b, end: end_b },
+ ) => {
+ let len_a = end_a - offset_a;
+ let len_b = end_b - offset_b;
+ let a = alloc_a.get_bytes(
+ &tcx,
+ // invent a pointer, only the offset is relevant anyway
+ Pointer::new(AllocId(0), Size::from_bytes(offset_a as u64)),
+ Size::from_bytes(len_a as u64),
+ );
+ let b = alloc_b.get_bytes(
+ &tcx,
+ // invent a pointer, only the offset is relevant anyway
+ Pointer::new(AllocId(0), Size::from_bytes(offset_b as u64)),
+ Size::from_bytes(len_b as u64),
+ );
+ if let (Ok(a), Ok(b)) = (a, b) {
+ return from_bool(a == b);
}
}
_ => (),