Change:
the compiler unexpectedly panicked. this is a bug. I tried this code (hyper = "0.11.9"): I expected to see this happen: code compiles (two top branches are incompatible) Instead, this happened: compiler crashed; re-ordering two top branches fixes the issue : Backtrace:
Slightly simplified version (it's not valid Rust code -- not all patterns are covered -- but it crashes the compiler): Backtrace with debug logging from rustc (RUSTBACKTRACE=full RUSTLOG=rustcconsteval):
Minified:

Discussion:
///   (1) all_constructors will only return constructors that are statically ///       possible. eg. it will only return Ok for Result<T, !> /// <del> /// Whether a vector `v` of patterns is 'useful' in relation to a set of such /// vectors `m` is defined as there being a set of inputs that will match `v` /// but not any of the sets in `m`. </del> <ins> /// This finds whether a (row) vector `v` of patterns is 'useful' in relation /// to a set of such vectors `m` - this is defined as there being a set of /// inputs that will match `v` but not any of the sets in `m`. /// /// All the patterns at each column of the `matrix ++ v` matrix must /// have the same type, except that wildcard (PatternKind::Wild) patterns /// with type TyErr are also allowed, even if the "type of the column" /// is not TyErr. That is used to represent private fields, as using their /// real type would assert that they are inhabited. </ins> /// /// This is used both for reachability checking (if a pattern isn't useful in /// relation to preceding patterns, it is not reachable) and exhaustiveness /// checking (if a wildcard pattern is useful in relation to a matrix, the /// matrix isn't exhaustive). pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, <del> matrix: &Matrix<'p, 'tcx>, v: &[&'p Pattern<'tcx>], witness: WitnessPreference) -> Usefulness<'tcx> { </del> <ins> matrix: &Matrix<'p, 'tcx>, v: &[&'p Pattern<'tcx>], witness: WitnessPreference) -> Usefulness<'tcx> { </ins> let &Matrix(ref rows) = matrix; debug!("is_useful({:?}, {:?})", matrix, v);

assert!(rows.iter().all(|r| r.len() == v.len())); let pcx = PatternContext { <ins> // TyErr is used to represent the type of wildcard patterns matching // against inaccessible (private) fields of structs, so that we won't // be able to observe whether the types of the struct's fields are // inhabited. // // If the field is truely inaccessible, then all the patterns // matching against it must be wildcard patterns, so its type // does not matter. // // However, if we are matching against non-wildcard patterns, we // need to know the real type of the field so we can specialize // against it. This primarily occurs through constants - they // can include contents for fields that are inaccessible at the // location of the match. In that case, the field's type is // inhabited - by the constant - so we can just use it. // // FIXME: this might lead to "unstable" behavior with macro hygiene // introducing uninhabited patterns for inaccessible fields. We // need to figure out how to model that. </ins> ty: rows.iter().map(|r| r[0].ty).find(|ty| !ty.references_error()) .unwrap_or(v[0].ty), max_slice_length: max_slice_length(cx, rows.iter().map(|r| r[0]).chain(Some(v[0])))

if is_visible { field.ty(cx.tcx, substs) } else { <del> // Treat all non-visible fields as nil. They </del> <ins> // Treat all non-visible fields as TyErr. They </ins> // can't appear in any other pattern from // this match (because they are private), // so their type does not matter - but // we don't want to know they are // uninhabited. <del> cx.tcx.mk_nil() </del> <ins> cx.tcx.types.err </ins> } }).collect() }

<ins> // Copyright 2017 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. mod my_mod { #[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)] pub struct Name<'a> { source: &'a str, } pub const JSON: Name = Name { source: "JSON" }; } pub fn crash() -> bool { match (my_mod::JSON, None) { (_, Some(my_mod::JSON)) => true, (my_mod::JSON, None) => true, _ => false, } } fn main() {} </ins>