use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization::{cmt};
use rustc::hir::pat_util::*;
-use rustc::traits::ProjectionMode;
+use rustc::traits::Reveal;
use rustc::ty::*;
use rustc::ty;
use std::cmp::Ordering;
// Check for empty enum, because is_useful only works on inhabited types.
let pat_ty = cx.tcx.node_id_to_type(scrut.id);
if inlined_arms.is_empty() {
- if !pat_ty.is_empty(cx.tcx) {
+ if !pat_ty.is_uninhabited(cx.tcx) {
// We know the type is inhabited, so this must be wrong
let mut err = struct_span_err!(cx.tcx.sess, ex.span, E0002,
"non-exhaustive patterns: type {} is non-empty",
possibly adding wildcards or more match arms.");
err.emit();
}
- // If the type *is* empty, it's vacuously exhaustive
+ // If the type *is* uninhabited, it's vacuously exhaustive
return;
}
.flat_map(|arm| &arm.0)
.map(|pat| vec![wrap_pat(cx, &pat)])
.collect();
- check_exhaustive(cx, ex.span, &matrix, source);
+ check_exhaustive(cx, scrut.span, &matrix, source);
},
_ => ()
}
let &(ref first_arm_pats, _) = &arms[0];
let first_pat = &first_arm_pats[0];
let span = first_pat.span;
- span_err!(cx.tcx.sess, span, E0162, "irrefutable if-let pattern");
+ struct_span_err!(cx.tcx.sess, span, E0162,
+ "irrefutable if-let pattern")
+ .span_label(span, &format!("irrefutable pattern"))
+ .emit();
printed_if_let_err = true;
}
},
format!("`{}` and {} more", head.join("`, `"), tail.len())
}
};
- span_err!(cx.tcx.sess, sp, E0004,
+
+ let label_text = match pattern_strings.len(){
+ 1 => format!("pattern {} not covered", joined_patterns),
+ _ => format!("patterns {} not covered", joined_patterns)
+ };
+ struct_span_err!(cx.tcx.sess, sp, E0004,
"non-exhaustive patterns: {} not covered",
joined_patterns
- );
+ ).span_label(sp, &label_text).emit();
},
}
}
// x @ Foo(..) is legal, but x @ Foo(y) isn't.
if sub.map_or(false, |p| pat_contains_bindings(&p)) {
- span_err!(cx.tcx.sess, p.span, E0007, "cannot bind by-move with sub-bindings");
+ struct_span_err!(cx.tcx.sess, p.span, E0007,
+ "cannot bind by-move with sub-bindings")
+ .span_label(p.span, &format!("binds an already bound by-move value by moving it"))
+ .emit();
} else if has_guard {
- span_err!(cx.tcx.sess, p.span, E0008, "cannot bind by-move into a pattern guard");
+ struct_span_err!(cx.tcx.sess, p.span, E0008,
+ "cannot bind by-move into a pattern guard")
+ .span_label(p.span, &format!("moves value into pattern guard"))
+ .emit();
} else if by_ref_span.is_some() {
let mut err = struct_span_err!(cx.tcx.sess, p.span, E0009,
"cannot bind by-move and by-ref in the same pattern");
let pat_ty = cx.tcx.node_id_to_type(p.id);
//FIXME: (@jroesch) this code should be floated up as well
cx.tcx.infer_ctxt(None, Some(cx.param_env.clone()),
- ProjectionMode::AnyFinal).enter(|infcx| {
+ Reveal::NotSpecializable).enter(|infcx| {
if infcx.type_moves_by_default(pat_ty, pat.span) {
check_move(p, sub.as_ref().map(|p| &**p));
}
fn check_for_mutation_in_guard<'a, 'tcx>(cx: &'a MatchCheckCtxt<'a, 'tcx>,
guard: &hir::Expr) {
cx.tcx.infer_ctxt(None, Some(cx.param_env.clone()),
- ProjectionMode::AnyFinal).enter(|infcx| {
+ Reveal::NotSpecializable).enter(|infcx| {
let mut checker = MutationChecker {
cx: cx,
};