From d4bf1210bafcb28f0fc65bcd1c6a09545482b546 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 24 Jan 2019 16:03:19 -0800 Subject: [PATCH] Ignore `Infer` sty when relating MIR and user `Ty` --- src/librustc/mir/tcx.rs | 27 +++++++++++++------ .../borrow_check/nll/type_check/mod.rs | 3 +-- src/librustc_traits/type_op.rs | 3 +-- src/test/ui/issues/issue-57866.rs | 26 ++++++++++++++++++ 4 files changed, 47 insertions(+), 12 deletions(-) create mode 100644 src/test/ui/issues/issue-57866.rs diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index c5b884525da4b..f6b07d2da0c7e 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -25,6 +25,9 @@ static_assert!(PLACE_TY_IS_3_PTRS_LARGE: mem::size_of::>() <= 24 ); +#[derive(Debug)] +pub struct HitTyVar; + impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> { pub fn from_ty(ty: Ty<'tcx>) -> PlaceTy<'tcx> { PlaceTy::Ty { ty } @@ -75,7 +78,7 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> { elem: &PlaceElem<'tcx>) -> PlaceTy<'tcx> { - self.projection_ty_core(tcx, elem, |_, _, ty| -> Result, ()> { Ok(ty) }) + self.projection_ty_core(tcx, elem, |_, _, ty| -> Result, HitTyVar> { Ok(ty) }) .unwrap() } @@ -84,14 +87,14 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> { /// `Ty` or downcast variant corresponding to that projection. /// The `handle_field` callback must map a `Field` to its `Ty`, /// (which should be trivial when `T` = `Ty`). - pub fn projection_ty_core( + pub fn projection_ty_core( self, tcx: TyCtxt<'a, 'gcx, 'tcx>, elem: &ProjectionElem<'tcx, V, T>, - mut handle_field: impl FnMut(&Self, &Field, &T) -> Result, E>) - -> Result, E> - where - V: ::std::fmt::Debug, T: ::std::fmt::Debug + mut handle_field: impl FnMut(&Self, &Field, &T) -> Result, HitTyVar>, + ) -> Result, HitTyVar> + where + V: ::std::fmt::Debug, T: ::std::fmt::Debug { let answer = match *elem { ProjectionElem::Deref => { @@ -135,8 +138,16 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> { substs, variant_index: index } } - _ => { - bug!("cannot downcast non-ADT type: `{:?}`", self) + ty::Infer(..) => { // #57866 + return Err(HitTyVar); + } + ref sty => { + bug!( + "cannot downcast non-ADT type: `{:?}`, `{:?}`, `{:?}`", + self, + sty, + adt_def1, + ); } }, ProjectionElem::Field(ref f, ref fty) => diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 180aa1907e8d1..8ab5c874cf643 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -27,7 +27,7 @@ use rustc::infer::canonical::QueryRegionConstraint; use rustc::infer::outlives::env::RegionBoundPairs; use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin}; use rustc::mir::interpret::EvalErrorKind::BoundsCheck; -use rustc::mir::tcx::PlaceTy; +use rustc::mir::tcx::{PlaceTy, HitTyVar}; use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext}; use rustc::mir::*; use rustc::traits::query::type_op; @@ -1079,7 +1079,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { // // if we hit a ty var as we descend, then just skip the // attempt to relate the mir local with any type. - #[derive(Debug)] struct HitTyVar; let mut curr_projected_ty: Result; curr_projected_ty = Ok(PlaceTy::from_ty(ty)); diff --git a/src/librustc_traits/type_op.rs b/src/librustc_traits/type_op.rs index 52fcb5b80f4ae..f5f343bb4dbb1 100644 --- a/src/librustc_traits/type_op.rs +++ b/src/librustc_traits/type_op.rs @@ -3,7 +3,7 @@ use rustc::infer::canonical::{Canonical, QueryResponse}; use rustc::infer::InferCtxt; use rustc::hir::def_id::DefId; use rustc::mir::ProjectionKind; -use rustc::mir::tcx::PlaceTy; +use rustc::mir::tcx::{PlaceTy, HitTyVar}; use rustc::traits::query::type_op::ascribe_user_type::AscribeUserType; use rustc::traits::query::type_op::eq::Eq; use rustc::traits::query::type_op::normalize::Normalize; @@ -133,7 +133,6 @@ impl AscribeUserTypeCx<'me, 'gcx, 'tcx> { // if we hit a ty var as we descend, then just skip the // attempt to relate the mir local with any type. - struct HitTyVar; let mut curr_projected_ty: Result; curr_projected_ty = Ok(PlaceTy::from_ty(ty)); for proj in projs { diff --git a/src/test/ui/issues/issue-57866.rs b/src/test/ui/issues/issue-57866.rs new file mode 100644 index 0000000000000..2d079c75d6ea1 --- /dev/null +++ b/src/test/ui/issues/issue-57866.rs @@ -0,0 +1,26 @@ +// run-pass + +#![feature(type_alias_enum_variants)] + +enum Outer { + A(T) +} + +enum Inner { + A(i32) +} + +type OuterAlias = Outer; + +fn ice(x: OuterAlias) { + // Fine + match x { + OuterAlias::A(Inner::A(_)) => (), + } + // Not fine + match x { + OuterAlias::A(Inner::A(y)) => (), + } +} + +fn main() {}