Skip to content

Commit 5bc2868

Browse files
committed
make const_expr_to_pat fallible (but never have it actually fail)
1 parent 40deb27 commit 5bc2868

File tree

3 files changed

+52
-26
lines changed

3 files changed

+52
-26
lines changed

src/librustc/middle/check_match.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -478,15 +478,25 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
478478
Some(Def::Const(did)) => {
479479
let substs = Some(self.tcx.node_id_item_substs(pat.id).substs);
480480
if let Some((const_expr, _)) = lookup_const_by_id(self.tcx, did, substs) {
481-
const_expr_to_pat(self.tcx, const_expr, pat.span).map(|new_pat| {
482-
483-
if let Some(ref mut renaming_map) = self.renaming_map {
484-
// Record any renamings we do here
485-
record_renamings(const_expr, &pat, renaming_map);
481+
match const_expr_to_pat(self.tcx, const_expr, pat.span) {
482+
Ok(new_pat) => {
483+
if let Some(ref mut map) = self.renaming_map {
484+
// Record any renamings we do here
485+
record_renamings(const_expr, &pat, map);
486+
}
487+
new_pat
486488
}
487-
488-
new_pat
489-
})
489+
Err(def_id) => {
490+
// TODO back-compat
491+
self.failed = true;
492+
self.tcx.sess.span_err(
493+
pat.span,
494+
&format!("constants of the type `{}` \
495+
cannot be used in patterns",
496+
self.tcx.item_path_str(def_id)));
497+
pat
498+
}
499+
}
490500
} else {
491501
self.failed = true;
492502
span_err!(self.tcx.sess, pat.span, E0158,

src/librustc/middle/const_eval.rs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,13 @@ impl ConstVal {
323323
}
324324
}
325325

326-
pub fn const_expr_to_pat(tcx: &TyCtxt, expr: &Expr, span: Span) -> P<hir::Pat> {
326+
pub fn const_expr_to_pat(tcx: &ty::TyCtxt, expr: &Expr, span: Span)
327+
-> Result<P<hir::Pat>, DefId> {
327328
let pat = match expr.node {
328329
hir::ExprTup(ref exprs) =>
329-
PatKind::Tup(exprs.iter().map(|expr| const_expr_to_pat(tcx, &expr, span)).collect()),
330+
PatKind::Tup(try!(exprs.iter()
331+
.map(|expr| const_expr_to_pat(tcx, &expr, span))
332+
.collect())),
330333

331334
hir::ExprCall(ref callee, ref args) => {
332335
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> {
336339
let path = match def.full_def() {
337340
Def::Struct(def_id) => def_to_path(tcx, def_id),
338341
Def::Variant(_, variant_did) => def_to_path(tcx, variant_did),
339-
Def::Fn(..) => return P(hir::Pat {
342+
Def::Fn(..) => return Ok(P(hir::Pat {
340343
id: expr.id,
341344
node: PatKind::Lit(P(expr.clone())),
342345
span: span,
343-
}),
346+
})),
344347
_ => unreachable!()
345348
};
346-
let pats = args.iter().map(|expr| const_expr_to_pat(tcx, &expr, span)).collect();
349+
let pats = try!(args.iter()
350+
.map(|expr| const_expr_to_pat(tcx, &**expr, span))
351+
.collect());
347352
PatKind::TupleStruct(path, Some(pats))
348353
}
349354

350355
hir::ExprStruct(ref path, ref fields, None) => {
351-
let field_pats = fields.iter().map(|field| codemap::Spanned {
352-
span: codemap::DUMMY_SP,
353-
node: hir::FieldPat {
354-
name: field.name.node,
355-
pat: const_expr_to_pat(tcx, &field.expr, span),
356-
is_shorthand: false,
357-
},
358-
}).collect();
356+
let field_pats =
357+
try!(fields.iter()
358+
.map(|field| Ok(codemap::Spanned {
359+
span: codemap::DUMMY_SP,
360+
node: hir::FieldPat {
361+
name: field.name.node,
362+
pat: try!(const_expr_to_pat(tcx, &field.expr, span)),
363+
is_shorthand: false,
364+
},
365+
}))
366+
.collect());
359367
PatKind::Struct(path.clone(), field_pats, false)
360368
}
361369

362370
hir::ExprVec(ref exprs) => {
363-
let pats = exprs.iter().map(|expr| const_expr_to_pat(tcx, &expr, span)).collect();
371+
let pats = try!(exprs.iter()
372+
.map(|expr| const_expr_to_pat(tcx, &expr, span))
373+
.collect());
364374
PatKind::Vec(pats, None, hir::HirVec::new())
365375
}
366376

@@ -381,7 +391,7 @@ pub fn const_expr_to_pat(tcx: &TyCtxt, expr: &Expr, span: Span) -> P<hir::Pat> {
381391

382392
_ => PatKind::Lit(P(expr.clone()))
383393
};
384-
P(hir::Pat { id: expr.id, node: pat, span: span })
394+
Ok(P(hir::Pat { id: expr.id, node: pat, span: span }))
385395
}
386396

387397
pub fn eval_const_expr(tcx: &TyCtxt, e: &Expr) -> ConstVal {

src/librustc_mir/hair/cx/pattern.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,15 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> {
9090
let substs = Some(self.cx.tcx.node_id_item_substs(pat.id).substs);
9191
match const_eval::lookup_const_by_id(self.cx.tcx, def_id, substs) {
9292
Some((const_expr, _const_ty)) => {
93-
let pat = const_eval::const_expr_to_pat(self.cx.tcx, const_expr,
94-
pat.span);
95-
return self.to_pattern(&pat);
93+
match const_eval::const_expr_to_pat(self.cx.tcx,
94+
const_expr,
95+
pat.span) {
96+
Ok(pat) =>
97+
return self.to_pattern(&pat),
98+
Err(_) =>
99+
self.cx.tcx.sess.span_bug(
100+
pat.span, "illegal constant"),
101+
}
96102
}
97103
None => {
98104
self.cx.tcx.sess.span_bug(

0 commit comments

Comments
 (0)