Fix ICE related to #53708

This commit is contained in:
Esteban Küber 2019-04-19 14:53:34 -07:00
parent 6e723c24a8
commit 56b1ec06ee
7 changed files with 47 additions and 26 deletions

View File

@ -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<T>(&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)
)
}
}

View File

@ -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,

View File

@ -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, _),

View File

@ -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
}

View File

@ -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 => {}
}
}

View File

@ -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
LL | C => {}
| ^
error[E0004]: non-exhaustive patterns: `&T` not covered
--> $DIR/match_ice.rs:15:11
|
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[E0277]: can't compare `S` with `S`
|
= 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`
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`.

View File

@ -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