Introduce TyCtxt::expect_def/expect_resolution helpers and use them where possible

This commit is contained in:
Vadim Petrochenkov 2016-06-03 23:15:00 +03:00
parent 4c30f6405c
commit ee4e55398b
42 changed files with 276 additions and 472 deletions

View file

@ -245,8 +245,7 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat)
if let PatKind::Binding(hir::BindByValue(hir::MutImmutable), name, None) = p.node {
let pat_ty = cx.tcx.pat_ty(p);
if let ty::TyEnum(edef, _) = pat_ty.sty {
let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
if let Some(Def::Local(..)) = def {
if let Def::Local(..) = cx.tcx.expect_def(p.id) {
if edef.variants.iter().any(|variant|
variant.name == name.node.unhygienize()
&& variant.kind() == VariantKind::Unit
@ -492,9 +491,8 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
return match pat.node {
PatKind::Path(..) | PatKind::QPath(..) => {
let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
match def {
Some(Def::AssociatedConst(did)) | Some(Def::Const(did)) => {
match self.tcx.expect_def(pat.id) {
Def::AssociatedConst(did) | Def::Const(did) => {
let substs = Some(self.tcx.node_id_item_substs(pat.id).substs);
if let Some((const_expr, _)) = lookup_const_by_id(self.tcx, did, substs) {
match const_expr_to_pat(self.tcx, const_expr, pat.id, pat.span) {
@ -788,7 +786,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
let pat = raw_pat(p);
match pat.node {
PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) =>
match cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def() {
match cx.tcx.expect_def(pat.id) {
Def::Const(..) | Def::AssociatedConst(..) =>
span_bug!(pat.span, "const pattern should've \
been rewritten"),
@ -903,21 +901,19 @@ pub fn specialize<'a, 'b, 'tcx>(
Some(vec![dummy_pat; arity]),
PatKind::Path(..) => {
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
match def {
match cx.tcx.expect_def(pat_id) {
Def::Const(..) | Def::AssociatedConst(..) =>
span_bug!(pat_span, "const pattern should've \
been rewritten"),
Def::Variant(_, id) if *constructor != Variant(id) => None,
Def::Variant(..) | Def::Struct(..) => Some(Vec::new()),
_ => span_bug!(pat_span, "specialize: unexpected \
def => span_bug!(pat_span, "specialize: unexpected \
definition {:?}", def),
}
}
PatKind::TupleStruct(_, ref args, ddpos) => {
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
match def {
match cx.tcx.expect_def(pat_id) {
Def::Const(..) | Def::AssociatedConst(..) =>
span_bug!(pat_span, "const pattern should've \
been rewritten"),
@ -944,10 +940,9 @@ pub fn specialize<'a, 'b, 'tcx>(
}
PatKind::Struct(_, ref pattern_fields, _) => {
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
let adt = cx.tcx.node_id_to_type(pat_id).ty_adt_def().unwrap();
let variant = constructor.variant_for_adt(adt);
let def_variant = adt.variant_of_def(def);
let def_variant = adt.variant_of_def(cx.tcx.expect_def(pat_id));
if variant.did == def_variant.did {
Some(variant.fields.iter().map(|sf| {
match pattern_fields.iter().find(|f| f.node.name == sf.name) {

View file

@ -19,7 +19,7 @@ use rustc::hir::map as ast_map;
use rustc::hir::map::blocks::FnLikeNode;
use rustc::middle::cstore::{self, InlinedItem};
use rustc::traits;
use rustc::hir::def::Def;
use rustc::hir::def::{Def, PathResolution};
use rustc::hir::def_id::DefId;
use rustc::hir::pat_util::def_to_path;
use rustc::ty::{self, Ty, TyCtxt, subst};
@ -276,11 +276,11 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
.collect()), None),
hir::ExprCall(ref callee, ref args) => {
let def = *tcx.def_map.borrow().get(&callee.id).unwrap();
let def = tcx.expect_def(callee.id);
if let Vacant(entry) = tcx.def_map.borrow_mut().entry(expr.id) {
entry.insert(def);
entry.insert(PathResolution::new(def));
}
let path = match def.full_def() {
let path = match def {
Def::Struct(def_id) => def_to_path(tcx, def_id),
Def::Variant(_, variant_did) => def_to_path(tcx, variant_did),
Def::Fn(..) | Def::Method(..) => return Ok(P(hir::Pat {
@ -322,12 +322,9 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
hir::ExprPath(_, ref path) => {
let opt_def = tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def());
match opt_def {
Some(Def::Struct(..)) | Some(Def::Variant(..)) =>
PatKind::Path(path.clone()),
Some(Def::Const(def_id)) |
Some(Def::AssociatedConst(def_id)) => {
match tcx.expect_def(expr.id) {
Def::Struct(..) | Def::Variant(..) => PatKind::Path(path.clone()),
Def::Const(def_id) | Def::AssociatedConst(def_id) => {
let substs = Some(tcx.node_id_item_substs(expr.id).substs);
let (expr, _ty) = lookup_const_by_id(tcx, def_id, substs).unwrap();
return const_expr_to_pat(tcx, expr, pat_id, span);
@ -714,21 +711,13 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
}
hir::ExprPath(..) => {
let opt_def = if let Some(def) = tcx.def_map.borrow().get(&e.id) {
// After type-checking, def_map contains definition of the
// item referred to by the path. During type-checking, it
// can contain the raw output of path resolution, which
// might be a partially resolved path.
// FIXME: There's probably a better way to make sure we don't
// panic here.
if def.depth != 0 {
signal!(e, UnresolvedPath);
}
def.full_def()
} else {
signal!(e, NonConstPath);
};
match opt_def {
// This function can be used before type checking when not all paths are fully resolved.
// FIXME: There's probably a better way to make sure we don't panic here.
let resolution = tcx.expect_resolution(e.id);
if resolution.depth != 0 {
signal!(e, UnresolvedPath);
}
match resolution.base_def {
Def::Const(def_id) |
Def::AssociatedConst(def_id) => {
let substs = if let ExprTypeChecked = ty_hint {