make `const_expr_to_pat` fallible (but never have it actually fail)
This commit is contained in:
parent
40deb279a8
commit
5bc2868060
|
@ -478,15 +478,25 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
|
|||
Some(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) {
|
||||
const_expr_to_pat(self.tcx, const_expr, pat.span).map(|new_pat| {
|
||||
|
||||
if let Some(ref mut renaming_map) = self.renaming_map {
|
||||
// Record any renamings we do here
|
||||
record_renamings(const_expr, &pat, renaming_map);
|
||||
match const_expr_to_pat(self.tcx, const_expr, pat.span) {
|
||||
Ok(new_pat) => {
|
||||
if let Some(ref mut map) = self.renaming_map {
|
||||
// Record any renamings we do here
|
||||
record_renamings(const_expr, &pat, map);
|
||||
}
|
||||
new_pat
|
||||
}
|
||||
|
||||
new_pat
|
||||
})
|
||||
Err(def_id) => {
|
||||
// TODO back-compat
|
||||
self.failed = true;
|
||||
self.tcx.sess.span_err(
|
||||
pat.span,
|
||||
&format!("constants of the type `{}` \
|
||||
cannot be used in patterns",
|
||||
self.tcx.item_path_str(def_id)));
|
||||
pat
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.failed = true;
|
||||
span_err!(self.tcx.sess, pat.span, E0158,
|
||||
|
|
|
@ -323,10 +323,13 @@ impl ConstVal {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn const_expr_to_pat(tcx: &TyCtxt, expr: &Expr, span: Span) -> P<hir::Pat> {
|
||||
pub fn const_expr_to_pat(tcx: &ty::TyCtxt, expr: &Expr, span: Span)
|
||||
-> Result<P<hir::Pat>, DefId> {
|
||||
let pat = match expr.node {
|
||||
hir::ExprTup(ref exprs) =>
|
||||
PatKind::Tup(exprs.iter().map(|expr| const_expr_to_pat(tcx, &expr, span)).collect()),
|
||||
PatKind::Tup(try!(exprs.iter()
|
||||
.map(|expr| const_expr_to_pat(tcx, &expr, span))
|
||||
.collect())),
|
||||
|
||||
hir::ExprCall(ref callee, ref args) => {
|
||||
let def = *tcx.def_map.borrow().get(&callee.id).unwrap();
|
||||
|
@ -336,31 +339,38 @@ pub fn const_expr_to_pat(tcx: &TyCtxt, expr: &Expr, span: Span) -> P<hir::Pat> {
|
|||
let path = match def.full_def() {
|
||||
Def::Struct(def_id) => def_to_path(tcx, def_id),
|
||||
Def::Variant(_, variant_did) => def_to_path(tcx, variant_did),
|
||||
Def::Fn(..) => return P(hir::Pat {
|
||||
Def::Fn(..) => return Ok(P(hir::Pat {
|
||||
id: expr.id,
|
||||
node: PatKind::Lit(P(expr.clone())),
|
||||
span: span,
|
||||
}),
|
||||
})),
|
||||
_ => unreachable!()
|
||||
};
|
||||
let pats = args.iter().map(|expr| const_expr_to_pat(tcx, &expr, span)).collect();
|
||||
let pats = try!(args.iter()
|
||||
.map(|expr| const_expr_to_pat(tcx, &**expr, span))
|
||||
.collect());
|
||||
PatKind::TupleStruct(path, Some(pats))
|
||||
}
|
||||
|
||||
hir::ExprStruct(ref path, ref fields, None) => {
|
||||
let field_pats = fields.iter().map(|field| codemap::Spanned {
|
||||
span: codemap::DUMMY_SP,
|
||||
node: hir::FieldPat {
|
||||
name: field.name.node,
|
||||
pat: const_expr_to_pat(tcx, &field.expr, span),
|
||||
is_shorthand: false,
|
||||
},
|
||||
}).collect();
|
||||
let field_pats =
|
||||
try!(fields.iter()
|
||||
.map(|field| Ok(codemap::Spanned {
|
||||
span: codemap::DUMMY_SP,
|
||||
node: hir::FieldPat {
|
||||
name: field.name.node,
|
||||
pat: try!(const_expr_to_pat(tcx, &field.expr, span)),
|
||||
is_shorthand: false,
|
||||
},
|
||||
}))
|
||||
.collect());
|
||||
PatKind::Struct(path.clone(), field_pats, false)
|
||||
}
|
||||
|
||||
hir::ExprVec(ref exprs) => {
|
||||
let pats = exprs.iter().map(|expr| const_expr_to_pat(tcx, &expr, span)).collect();
|
||||
let pats = try!(exprs.iter()
|
||||
.map(|expr| const_expr_to_pat(tcx, &expr, span))
|
||||
.collect());
|
||||
PatKind::Vec(pats, None, hir::HirVec::new())
|
||||
}
|
||||
|
||||
|
@ -381,7 +391,7 @@ pub fn const_expr_to_pat(tcx: &TyCtxt, expr: &Expr, span: Span) -> P<hir::Pat> {
|
|||
|
||||
_ => PatKind::Lit(P(expr.clone()))
|
||||
};
|
||||
P(hir::Pat { id: expr.id, node: pat, span: span })
|
||||
Ok(P(hir::Pat { id: expr.id, node: pat, span: span }))
|
||||
}
|
||||
|
||||
pub fn eval_const_expr(tcx: &TyCtxt, e: &Expr) -> ConstVal {
|
||||
|
|
|
@ -90,9 +90,15 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> {
|
|||
let substs = Some(self.cx.tcx.node_id_item_substs(pat.id).substs);
|
||||
match const_eval::lookup_const_by_id(self.cx.tcx, def_id, substs) {
|
||||
Some((const_expr, _const_ty)) => {
|
||||
let pat = const_eval::const_expr_to_pat(self.cx.tcx, const_expr,
|
||||
pat.span);
|
||||
return self.to_pattern(&pat);
|
||||
match const_eval::const_expr_to_pat(self.cx.tcx,
|
||||
const_expr,
|
||||
pat.span) {
|
||||
Ok(pat) =>
|
||||
return self.to_pattern(&pat),
|
||||
Err(_) =>
|
||||
self.cx.tcx.sess.span_bug(
|
||||
pat.span, "illegal constant"),
|
||||
}
|
||||
}
|
||||
None => {
|
||||
self.cx.tcx.sess.span_bug(
|
||||
|
|
Loading…
Reference in New Issue