diff --git a/src/librustc/traits/codegen/mod.rs b/src/librustc/traits/codegen/mod.rs index 9b0a3820c859c..7e3d6d752ccdc 100644 --- a/src/librustc/traits/codegen/mod.rs +++ b/src/librustc/traits/codegen/mod.rs @@ -5,9 +5,7 @@ use crate::dep_graph::{DepKind, DepTrackingMapConfig}; use std::marker::PhantomData; -use syntax_pos::DUMMY_SP; use crate::infer::InferCtxt; -use syntax_pos::Span; use crate::traits::{FulfillmentContext, Obligation, ObligationCause, SelectionContext, TraitEngine, Vtable}; use crate::ty::{self, Ty, TyCtxt}; @@ -69,7 +67,7 @@ pub fn codegen_fulfill_obligation<'a, 'tcx>(ty: TyCtxt<'a, 'tcx, 'tcx>, debug!("fulfill_obligation: register_predicate_obligation {:?}", predicate); fulfill_cx.register_predicate_obligation(&infcx, predicate); }); - let vtable = infcx.drain_fulfillment_cx_or_panic(DUMMY_SP, &mut fulfill_cx, &vtable); + let vtable = infcx.drain_fulfillment_cx_or_panic(&mut fulfill_cx, &vtable); info!("Cache miss: {:?} => {:?}", trait_ref, vtable); vtable @@ -141,7 +139,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// unified, and hence we need to process those obligations to get /// the complete picture of the type. fn drain_fulfillment_cx_or_panic(&self, - span: Span, fulfill_cx: &mut FulfillmentContext<'tcx>, result: &T) -> T::Lifted @@ -153,15 +150,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // contains unbound type parameters. It could be a slight // optimization to stop iterating early. if let Err(errors) = fulfill_cx.select_all_or_error(self) { - span_bug!(span, "Encountered errors `{:?}` resolving bounds after type-checking", - errors); + bug!("Encountered errors `{:?}` resolving bounds after type-checking", errors); } let result = self.resolve_type_vars_if_possible(result); let result = self.tcx.erase_regions(&result); self.tcx.lift_to_global(&result).unwrap_or_else(|| - span_bug!(span, "Uninferred types/regions in `{:?}`", result) + bug!("Uninferred types/regions in `{:?}`", result) ) } } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 40612ab931ada..9a90ccda9140c 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -85,7 +85,7 @@ impl BoundRegion { /// N.B., if you change this, you'll probably want to change the corresponding /// AST structure in `libsyntax/ast.rs` as well. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, - RustcEncodable, RustcDecodable, HashStable)] + RustcEncodable, RustcDecodable, HashStable, Debug)] pub enum TyKind<'tcx> { /// The primitive boolean type. Written as `bool`. Bool, diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index a9c521f59a96c..c41a09aecaad6 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -211,6 +211,7 @@ impl<'a, 'tcx> LiteralExpander<'a, 'tcx> { // the constant's pointee type crty: Ty<'tcx>, ) -> ConstValue<'tcx> { + debug!("fold_const_value_deref {:?} {:?} {:?}", val, rty, crty); match (val, &crty.sty, &rty.sty) { // the easy case, deref a reference (ConstValue::Scalar(Scalar::Ptr(p)), x, y) if x == y => ConstValue::ByRef( @@ -238,6 +239,7 @@ impl<'a, 'tcx> LiteralExpander<'a, 'tcx> { impl<'a, 'tcx> PatternFolder<'tcx> for LiteralExpander<'a, 'tcx> { fn fold_pattern(&mut self, pat: &Pattern<'tcx>) -> Pattern<'tcx> { + debug!("fold_pattern {:?} {:?} {:?}", pat, pat.ty.sty, pat.kind); match (&pat.ty.sty, &*pat.kind) { ( &ty::Ref(_, rty, _), diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index fc12443c0923a..aff9d7b8eb0db 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -974,10 +974,25 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { PatternKind::Wild } ty::Adt(adt_def, _) if !self.tcx.has_attr(adt_def.did, "structural_match") => { - let msg = format!("to use a constant of type `{}` in a pattern, \ - `{}` must be annotated with `#[derive(PartialEq, Eq)]`", - self.tcx.def_path_str(adt_def.did), - self.tcx.def_path_str(adt_def.did)); + let path = self.tcx.def_path_str(adt_def.did); + let msg = format!( + "to use a constant of type `{}` in a pattern, \ + `{}` must be annotated with `#[derive(PartialEq, Eq)]`", + path, + path, + ); + self.tcx.sess.span_err(span, &msg); + PatternKind::Wild + } + ty::Ref(_, ty::TyS { sty: ty::Adt(adt_def, _), .. }, _) + if !self.tcx.has_attr(adt_def.did, "structural_match") => { + let path = self.tcx.def_path_str(adt_def.did); + let msg = format!( + "to use a constant of type `{}` in a pattern, \ + `{}` must be annotated with `#[derive(PartialEq, Eq)]`", + path, + path, + ); self.tcx.sess.span_err(span, &msg); PatternKind::Wild } diff --git a/src/test/ui/consts/match_ice.rs b/src/test/ui/consts/match_ice.rs index 53c5782a4c70e..1c13bfceb6cc2 100644 --- a/src/test/ui/consts/match_ice.rs +++ b/src/test/ui/consts/match_ice.rs @@ -2,9 +2,17 @@ struct S; +#[derive(PartialEq, Eq)] +struct T; + fn main() { const C: &S = &S; - match C { //~ ERROR non-exhaustive - C => {} // this is a common bug around constants and references in patterns + match C { + C => {} + //~^ ERROR to use a constant of type `S` in a pattern, `S` must be annotated with + } + const K: &T = &T; + match K { //~ ERROR non-exhaustive patterns: `&T` not covered + K => {} } } diff --git a/src/test/ui/consts/match_ice.stderr b/src/test/ui/consts/match_ice.stderr index 64f0503242459..158581fcb1599 100644 --- a/src/test/ui/consts/match_ice.stderr +++ b/src/test/ui/consts/match_ice.stderr @@ -1,17 +1,17 @@ -error[E0004]: non-exhaustive patterns: `&S` not covered - --> $DIR/match_ice.rs:8:11 +error: to use a constant of type `S` in a pattern, `S` must be annotated with `#[derive(PartialEq, Eq)]` + --> $DIR/match_ice.rs:11:9 | -LL | match C { - | ^ pattern `&S` not covered - | - = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms +LL | C => {} + | ^ -error[E0277]: can't compare `S` with `S` +error[E0004]: non-exhaustive patterns: `&T` not covered + --> $DIR/match_ice.rs:15:11 | - = help: the trait `std::cmp::PartialEq` is not implemented for `S` - = note: required because of the requirements on the impl of `std::cmp::PartialEq` for `&S` +LL | match K { + | ^ pattern `&T` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error: aborting due to 2 previous errors -Some errors occurred: E0004, E0277. -For more information about an error, try `rustc --explain E0004`. +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/const-pat-ice.stderr b/src/test/ui/pattern/const-pat-ice.stderr index 03580dfecfb59..261e95229a76e 100644 --- a/src/test/ui/pattern/const-pat-ice.stderr +++ b/src/test/ui/pattern/const-pat-ice.stderr @@ -1,4 +1,4 @@ -thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir/hair/pattern/_match.rs:1069:5 +thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir/hair/pattern/_match.rs:1071:5 note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. error: internal compiler error: unexpected panic