pub struct PatternContext<'a, 'tcx: 'a> {
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
+ pub param_env: ty::ParamEnv<'tcx>,
pub tables: &'a ty::TypeckTables<'tcx>,
pub substs: &'tcx Substs<'tcx>,
pub errors: Vec<PatternError<'tcx>>,
impl<'a, 'tcx> Pattern<'tcx> {
pub fn from_hir(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+ param_env_and_substs: ty::ParamEnvAnd<'tcx, &'tcx Substs<'tcx>>,
tables: &'a ty::TypeckTables<'tcx>,
- substs: &'tcx Substs<'tcx>,
pat: &hir::Pat) -> Self {
- let mut pcx = PatternContext::new(tcx, tables, substs);
+ let mut pcx = PatternContext::new(tcx, param_env_and_substs, tables);
let result = pcx.lower_pattern(pat);
if !pcx.errors.is_empty() {
span_bug!(pat.span, "encountered errors lowering pattern: {:?}", pcx.errors)
impl<'a, 'tcx> PatternContext<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
- tables: &'a ty::TypeckTables<'tcx>,
- substs: &'tcx Substs<'tcx>) -> Self {
- PatternContext { tcx, tables, substs, errors: vec![] }
+ param_env_and_substs: ty::ParamEnvAnd<'tcx, &'tcx Substs<'tcx>>,
+ tables: &'a ty::TypeckTables<'tcx>) -> Self {
+ PatternContext {
+ tcx,
+ param_env: param_env_and_substs.param_env,
+ tables,
+ substs: param_env_and_substs.value,
+ errors: vec![]
+ }
}
pub fn lower_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
- let mut ty = self.tables.node_id_to_type(pat.id);
+ let mut ty = self.tables.node_id_to_type(pat.hir_id);
let kind = match pat.node {
PatKind::Wild => PatternKind::Wild,
}
PatKind::Path(ref qpath) => {
- return self.lower_path(qpath, pat.id, pat.id, pat.span);
+ return self.lower_path(qpath, pat.hir_id, pat.id, pat.span);
}
PatKind::Ref(ref subpattern, _) |
}
PatKind::Slice(ref prefix, ref slice, ref suffix) => {
- let ty = self.tables.node_id_to_type(pat.id);
+ let ty = self.tables.node_id_to_type(pat.hir_id);
match ty.sty {
ty::TyRef(_, mt) =>
PatternKind::Deref {
}
PatKind::Tuple(ref subpatterns, ddpos) => {
- let ty = self.tables.node_id_to_type(pat.id);
+ let ty = self.tables.node_id_to_type(pat.hir_id);
match ty.sty {
ty::TyTuple(ref tys, _) => {
let subpatterns =
}
}
- PatKind::Binding(bm, def_id, ref ident, ref sub) => {
+ PatKind::Binding(_, def_id, ref ident, ref sub) => {
let id = self.tcx.hir.as_local_node_id(def_id).unwrap();
- let var_ty = self.tables.node_id_to_type(pat.id);
+ let var_ty = self.tables.node_id_to_type(pat.hir_id);
let region = match var_ty.sty {
ty::TyRef(r, _) => Some(r),
_ => None,
};
+ let bm = *self.tables.pat_binding_modes().get(pat.hir_id)
+ .expect("missing binding mode");
let (mutability, mode) = match bm {
- hir::BindByValue(hir::MutMutable) =>
+ ty::BindByValue(hir::MutMutable) =>
(Mutability::Mut, BindingMode::ByValue),
- hir::BindByValue(hir::MutImmutable) =>
+ ty::BindByValue(hir::MutImmutable) =>
(Mutability::Not, BindingMode::ByValue),
- hir::BindByRef(hir::MutMutable) =>
- (Mutability::Not, BindingMode::ByRef(region.unwrap(), BorrowKind::Mut)),
- hir::BindByRef(hir::MutImmutable) =>
- (Mutability::Not, BindingMode::ByRef(region.unwrap(), BorrowKind::Shared)),
+ ty::BindByReference(hir::MutMutable) =>
+ (Mutability::Not, BindingMode::ByRef(
+ region.unwrap(), BorrowKind::Mut)),
+ ty::BindByReference(hir::MutImmutable) =>
+ (Mutability::Not, BindingMode::ByRef(
+ region.unwrap(), BorrowKind::Shared)),
};
// A ref x pattern is the same node used for x, and as such it has
// x's type, which is &T, where we want T (the type being matched).
- if let hir::BindByRef(_) = bm {
+ if let ty::BindByReference(_) = bm {
if let ty::TyRef(_, mt) = ty.sty {
ty = mt.ty;
} else {
}
PatKind::TupleStruct(ref qpath, ref subpatterns, ddpos) => {
- let def = self.tables.qpath_def(qpath, pat.id);
+ let def = self.tables.qpath_def(qpath, pat.hir_id);
let adt_def = match ty.sty {
ty::TyAdt(adt_def, _) => adt_def,
_ => span_bug!(pat.span, "tuple struct pattern not applied to an ADT"),
}
PatKind::Struct(ref qpath, ref fields, _) => {
- let def = self.tables.qpath_def(qpath, pat.id);
+ let def = self.tables.qpath_def(qpath, pat.hir_id);
let adt_def = match ty.sty {
ty::TyAdt(adt_def, _) => adt_def,
_ => {
fn lower_path(&mut self,
qpath: &hir::QPath,
- id: ast::NodeId,
+ id: hir::HirId,
pat_id: ast::NodeId,
span: Span)
-> Pattern<'tcx> {
let kind = match def {
Def::Const(def_id) | Def::AssociatedConst(def_id) => {
let substs = self.tables.node_substs(id);
- match eval::lookup_const_by_id(self.tcx, def_id, substs) {
+ match eval::lookup_const_by_id(self.tcx, self.param_env.and((def_id, substs))) {
Some((def_id, substs)) => {
// Enter the inlined constant's tables&substs temporarily.
let old_tables = self.tables;
}
fn lower_lit(&mut self, expr: &hir::Expr) -> PatternKind<'tcx> {
- let const_cx = eval::ConstContext::new(self.tcx, self.tables, self.substs);
+ let const_cx = eval::ConstContext::new(self.tcx,
+ self.param_env.and(self.substs),
+ self.tables);
match const_cx.eval(expr) {
Ok(value) => {
if let ConstVal::Variant(def_id) = value {
hir::ExprPath(ref qpath) => qpath,
_ => bug!()
};
- let ty = self.tables.node_id_to_type(callee.id);
- let def = self.tables.qpath_def(qpath, callee.id);
+ let ty = self.tables.node_id_to_type(callee.hir_id);
+ let def = self.tables.qpath_def(qpath, callee.hir_id);
match def {
Def::Fn(..) | Def::Method(..) => self.lower_lit(expr),
_ => {
}
hir::ExprStruct(ref qpath, ref fields, None) => {
- let def = self.tables.qpath_def(qpath, expr.id);
+ let def = self.tables.qpath_def(qpath, expr.hir_id);
let adt_def = match pat_ty.sty {
ty::TyAdt(adt_def, _) => adt_def,
_ => {
}
hir::ExprPath(ref qpath) => {
- return self.lower_path(qpath, expr.id, pat_id, span);
+ return self.lower_path(qpath, expr.hir_id, pat_id, span);
}
_ => self.lower_lit(expr)