diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 4a4280ba7dc4d..4546eadc6e6e1 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -138,7 +138,7 @@ impl FlagComputation { } &ty::Opaque(_, substs) => { - self.add_flags(TypeFlags::HAS_PROJECTION); + self.add_flags(TypeFlags::HAS_PROJECTION | TypeFlags::HAS_TY_OPAQUE); self.add_substs(substs); } diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 5ff0d04c1ed24..3212bc7241783 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -78,6 +78,9 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { fn has_projections(&self) -> bool { self.has_type_flags(TypeFlags::HAS_PROJECTION) } + fn has_opaque_types(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_OPAQUE) + } fn references_error(&self) -> bool { self.has_type_flags(TypeFlags::HAS_TY_ERR) } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 6d36116d782e6..45ea05efd4a84 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -481,6 +481,8 @@ bitflags! { const HAS_CT_INFER = 1 << 14; const HAS_CT_PLACEHOLDER = 1 << 15; + /// Does this have any [Opaque] types. + const HAS_TY_OPAQUE = 1 << 16; const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits | TypeFlags::HAS_RE_EARLY_BOUND.bits; @@ -503,7 +505,8 @@ bitflags! { TypeFlags::HAS_RE_ERASED.bits | TypeFlags::HAS_TY_PLACEHOLDER.bits | TypeFlags::HAS_CT_INFER.bits | - TypeFlags::HAS_CT_PLACEHOLDER.bits; + TypeFlags::HAS_CT_PLACEHOLDER.bits | + TypeFlags::HAS_TY_OPAQUE.bits; } } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index db7b8d8cfd9ed..f3c3d04931ac3 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -615,7 +615,7 @@ impl<'tcx> TyCtxt<'tcx> { fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { if let ty::Opaque(def_id, substs) = t.kind { self.expand_opaque_ty(def_id, substs).unwrap_or(t) - } else if t.has_projections() { + } else if t.has_opaque_types() { t.super_fold_with(self) } else { t diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index 2a2d864276067..88fe6d1a3a49d 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -1196,6 +1196,22 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { anon_ty={:?})", revealed_ty, anon_ty ); + + // Fast path for the common case. + if !anon_ty.has_opaque_types() { + if let Err(terr) = self.eq_types(anon_ty, revealed_ty, locations, category) { + span_mirbug!( + self, + locations, + "eq_opaque_type_and_type: `{:?}=={:?}` failed with `{:?}`", + revealed_ty, + anon_ty, + terr + ); + } + return Ok(()); + } + let infcx = self.infcx; let tcx = infcx.tcx; let param_env = self.param_env;