about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_middle/src/mir/query.rs3
-rw-r--r--compiler/rustc_middle/src/ty/context.rs3
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs6
-rw-r--r--compiler/rustc_mir/src/borrow_check/mod.rs5
-rw-r--r--compiler/rustc_mir/src/borrow_check/nll.rs9
-rw-r--r--compiler/rustc_mir/src/borrow_check/region_infer/opaque_types.rs18
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/mod.rs30
-rw-r--r--compiler/rustc_trait_selection/src/opaque_types.rs10
-rw-r--r--compiler/rustc_typeck/src/check/writeback.rs10
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs138
10 files changed, 134 insertions, 98 deletions
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index f6c8ed4cbab..9e61f5629ae 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -9,6 +9,7 @@ use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_index::bit_set::BitMatrix;
 use rustc_index::vec::IndexVec;
+use rustc_middle::ty::OpaqueTypeKey;
 use rustc_span::Span;
 use rustc_target::abi::VariantIdx;
 use smallvec::SmallVec;
@@ -210,7 +211,7 @@ pub struct BorrowCheckResult<'tcx> {
     /// All the opaque types that are restricted to concrete types
     /// by this function. Unlike the value in `TypeckResults`, this has
     /// unerased regions.
-    pub concrete_opaque_types: VecMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
+    pub concrete_opaque_types: VecMap<OpaqueTypeKey<'tcx>, ty::ResolvedOpaqueTy<'tcx>>,
     pub closure_requirements: Option<ClosureRegionRequirements<'tcx>>,
     pub used_mut_upvars: SmallVec<[Field; 8]>,
 }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index ee8fa4b647a..d4433ebd350 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -48,6 +48,7 @@ use rustc_hir::{
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_macros::HashStable;
 use rustc_middle::mir::FakeReadCause;
+use rustc_middle::ty::OpaqueTypeKey;
 use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
 use rustc_session::config::{BorrowckMode, CrateType, OutputFilenames};
 use rustc_session::lint::{Level, Lint};
@@ -425,7 +426,7 @@ pub struct TypeckResults<'tcx> {
 
     /// All the opaque types that are restricted to concrete types
     /// by this function.
-    pub concrete_opaque_types: VecMap<DefId, ResolvedOpaqueTy<'tcx>>,
+    pub concrete_opaque_types: VecMap<OpaqueTypeKey<'tcx>, ResolvedOpaqueTy<'tcx>>,
 
     /// Tracks the minimum captures required for a closure;
     /// see `MinCaptureInformationMap` for more details.
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index b58c92b8415..268818b64e5 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -835,6 +835,12 @@ impl<'tcx> InstantiatedPredicates<'tcx> {
     }
 }
 
+#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
+pub struct OpaqueTypeKey<'tcx> {
+    pub def_id: DefId,
+    pub substs: SubstsRef<'tcx>,
+}
+
 rustc_index::newtype_index! {
     /// "Universes" are used during type- and trait-checking in the
     /// presence of `for<..>` binders to control what sets of names are
diff --git a/compiler/rustc_mir/src/borrow_check/mod.rs b/compiler/rustc_mir/src/borrow_check/mod.rs
index 5b2aaf56921..36eb8a4baa8 100644
--- a/compiler/rustc_mir/src/borrow_check/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/mod.rs
@@ -2,7 +2,6 @@
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::graph::dominators::Dominators;
-use rustc_data_structures::vec_map::VecMap;
 use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorReported};
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
@@ -26,7 +25,7 @@ use either::Either;
 use smallvec::SmallVec;
 use std::cell::RefCell;
 use std::collections::BTreeMap;
-use std::iter::{self, FromIterator};
+use std::iter;
 use std::mem;
 use std::rc::Rc;
 
@@ -442,7 +441,7 @@ fn do_mir_borrowck<'a, 'tcx>(
     }
 
     let result = BorrowCheckResult {
-        concrete_opaque_types: VecMap::from_iter(opaque_type_values.into_iter()),
+        concrete_opaque_types: opaque_type_values,
         closure_requirements: opt_closure_req,
         used_mut_upvars: mbcx.used_mut_upvars,
     };
diff --git a/compiler/rustc_mir/src/borrow_check/nll.rs b/compiler/rustc_mir/src/borrow_check/nll.rs
index a0265b20d12..fdc06ae303a 100644
--- a/compiler/rustc_mir/src/borrow_check/nll.rs
+++ b/compiler/rustc_mir/src/borrow_check/nll.rs
@@ -1,15 +1,14 @@
 //! The entry point of the NLL borrow checker.
 
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::vec_map::VecMap;
 use rustc_errors::Diagnostic;
-use rustc_hir::def_id::DefId;
 use rustc_index::vec::IndexVec;
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::mir::{
     BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
     Promoted,
 };
-use rustc_middle::ty::{self, RegionKind, RegionVid};
+use rustc_middle::ty::{self, OpaqueTypeKey, RegionKind, RegionVid};
 use rustc_span::symbol::sym;
 use std::env;
 use std::fmt::Debug;
@@ -47,7 +46,7 @@ crate type PoloniusOutput = Output<RustcFacts>;
 /// closure requirements to propagate, and any generated errors.
 crate struct NllOutput<'tcx> {
     pub regioncx: RegionInferenceContext<'tcx>,
-    pub opaque_type_values: FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
+    pub opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, ty::ResolvedOpaqueTy<'tcx>>,
     pub polonius_output: Option<Rc<PoloniusOutput>>,
     pub opt_closure_req: Option<ClosureRegionRequirements<'tcx>>,
     pub nll_errors: RegionErrors<'tcx>,
@@ -367,7 +366,7 @@ pub(super) fn dump_annotation<'a, 'tcx>(
     body: &Body<'tcx>,
     regioncx: &RegionInferenceContext<'tcx>,
     closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
-    opaque_type_values: &FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
+    opaque_type_values: &VecMap<OpaqueTypeKey<'tcx>, ty::ResolvedOpaqueTy<'tcx>>,
     errors_buffer: &mut Vec<Diagnostic>,
 ) {
     let tcx = infcx.tcx;
diff --git a/compiler/rustc_mir/src/borrow_check/region_infer/opaque_types.rs b/compiler/rustc_mir/src/borrow_check/region_infer/opaque_types.rs
index 0d1d2551042..b1954e9938d 100644
--- a/compiler/rustc_mir/src/borrow_check/region_infer/opaque_types.rs
+++ b/compiler/rustc_mir/src/borrow_check/region_infer/opaque_types.rs
@@ -1,7 +1,6 @@
-use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::def_id::DefId;
+use rustc_data_structures::vec_map::VecMap;
 use rustc_infer::infer::InferCtxt;
-use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{self, OpaqueTypeKey, TyCtxt, TypeFoldable};
 use rustc_span::Span;
 use rustc_trait_selection::opaque_types::InferCtxtExt;
 
@@ -51,12 +50,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     pub(in crate::borrow_check) fn infer_opaque_types(
         &self,
         infcx: &InferCtxt<'_, 'tcx>,
-        opaque_ty_decls: FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
+        opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, ty::ResolvedOpaqueTy<'tcx>>,
         span: Span,
-    ) -> FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>> {
+    ) -> VecMap<OpaqueTypeKey<'tcx>, ty::ResolvedOpaqueTy<'tcx>> {
         opaque_ty_decls
             .into_iter()
-            .map(|(opaque_def_id, ty::ResolvedOpaqueTy { concrete_type, substs })| {
+            .map(|(opaque_type_key, ty::ResolvedOpaqueTy { concrete_type, substs })| {
                 debug!(?concrete_type, ?substs);
 
                 let mut subst_regions = vec![self.universal_regions.fr_static];
@@ -110,14 +109,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
                 debug!(?universal_concrete_type, ?universal_substs);
 
+                let opaque_type_key =
+                    OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs };
                 let remapped_type = infcx.infer_opaque_definition_from_instantiation(
-                    opaque_def_id,
-                    universal_substs,
+                    opaque_type_key,
                     universal_concrete_type,
                     span,
                 );
                 (
-                    opaque_def_id,
+                    opaque_type_key,
                     ty::ResolvedOpaqueTy { concrete_type: remapped_type, substs: universal_substs },
                 )
             })
diff --git a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
index 4b9569b74b9..26ae3f4b5c8 100644
--- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
@@ -7,9 +7,10 @@ use either::Either;
 
 use rustc_data_structures::frozen::Frozen;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::vec_map::VecMap;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::LocalDefId;
 use rustc_hir::lang_items::LangItem;
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_infer::infer::canonical::QueryRegionConstraints;
@@ -27,8 +28,8 @@ use rustc_middle::ty::cast::CastTy;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef, UserSubsts};
 use rustc_middle::ty::{
-    self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, RegionVid, ToPredicate, Ty,
-    TyCtxt, UserType, UserTypeAnnotationIndex, WithConstness,
+    self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, OpaqueTypeKey, RegionVid,
+    ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, WithConstness,
 };
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::VariantIdx;
@@ -818,7 +819,7 @@ struct TypeChecker<'a, 'tcx> {
     reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
     borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
     universal_region_relations: &'a UniversalRegionRelations<'tcx>,
-    opaque_type_values: FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
+    opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, ty::ResolvedOpaqueTy<'tcx>>,
 }
 
 struct BorrowCheckContext<'a, 'tcx> {
@@ -833,7 +834,7 @@ struct BorrowCheckContext<'a, 'tcx> {
 crate struct MirTypeckResults<'tcx> {
     crate constraints: MirTypeckRegionConstraints<'tcx>,
     pub(in crate::borrow_check) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
-    crate opaque_type_values: FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
+    crate opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, ty::ResolvedOpaqueTy<'tcx>>,
 }
 
 /// A collection of region constraints that must be satisfied for the
@@ -978,7 +979,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             borrowck_context,
             reported_errors: Default::default(),
             universal_region_relations,
-            opaque_type_values: FxHashMap::default(),
+            opaque_type_values: VecMap::default(),
         };
         checker.check_user_type_annotations();
         checker
@@ -1240,7 +1241,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         let param_env = self.param_env;
         let body = self.body;
         let concrete_opaque_types = &tcx.typeck(anon_owner_def_id).concrete_opaque_types;
-        let mut opaque_type_values = Vec::new();
+        let mut opaque_type_values = VecMap::new();
 
         debug!("eq_opaque_type_and_type: mir_def_id={:?}", body.source.def_id());
         let opaque_type_map = self.fully_perform_op(
@@ -1288,7 +1289,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         } else {
                             false
                         };
-                        let opaque_defn_ty = match concrete_opaque_types.get(&opaque_def_id) {
+
+                        let opaque_type_key =
+                            OpaqueTypeKey { def_id: opaque_def_id, substs: opaque_decl.substs };
+                        let opaque_defn_ty = match concrete_opaque_types
+                            .iter()
+                            .find(|(opaque_type_key, _)| opaque_type_key.def_id == opaque_def_id)
+                            .map(|(_, resolved_opaque_ty)| resolved_opaque_ty)
+                        {
                             None => {
                                 if !concrete_is_opaque {
                                     tcx.sess.delay_span_bug(
@@ -1322,13 +1330,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                                     .at(&ObligationCause::dummy(), param_env)
                                     .eq(opaque_decl.concrete_ty, renumbered_opaque_defn_ty)?,
                             );
-                            opaque_type_values.push((
-                                opaque_def_id,
+                            opaque_type_values.insert(
+                                opaque_type_key,
                                 ty::ResolvedOpaqueTy {
                                     concrete_type: renumbered_opaque_defn_ty,
                                     substs: opaque_decl.substs,
                                 },
-                            ));
+                            );
                         } else {
                             // We're using an opaque `impl Trait` type without
                             // 'revealing' it. For example, code like this:
diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs
index 2fdb267d0db..fc497755b3c 100644
--- a/compiler/rustc_trait_selection/src/opaque_types.rs
+++ b/compiler/rustc_trait_selection/src/opaque_types.rs
@@ -12,7 +12,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
 use rustc_infer::infer::{self, InferCtxt, InferOk};
 use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor};
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef};
-use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt};
 use rustc_span::Span;
 
 use std::ops::ControlFlow;
@@ -143,8 +143,7 @@ pub trait InferCtxtExt<'tcx> {
 
     fn infer_opaque_definition_from_instantiation(
         &self,
-        def_id: DefId,
-        substs: SubstsRef<'tcx>,
+        opaque_type_key: OpaqueTypeKey<'tcx>,
         instantiated_ty: Ty<'tcx>,
         span: Span,
     ) -> Ty<'tcx>;
@@ -573,11 +572,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
     ///   `opaque_defn.concrete_ty`
     fn infer_opaque_definition_from_instantiation(
         &self,
-        def_id: DefId,
-        substs: SubstsRef<'tcx>,
+        opaque_type_key: OpaqueTypeKey<'tcx>,
         instantiated_ty: Ty<'tcx>,
         span: Span,
     ) -> Ty<'tcx> {
+        let OpaqueTypeKey { def_id, substs } = opaque_type_key;
+
         debug!(
             "infer_opaque_definition_from_instantiation(def_id={:?}, instantiated_ty={:?})",
             def_id, instantiated_ty
diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs
index 685f81b3bd6..ec940cb3693 100644
--- a/compiler/rustc_typeck/src/check/writeback.rs
+++ b/compiler/rustc_typeck/src/check/writeback.rs
@@ -15,7 +15,7 @@ use rustc_middle::hir::place::Place as HirPlace;
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
-use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt};
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 use rustc_trait_selection::opaque_types::InferCtxtExt;
@@ -493,9 +493,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
             // fn foo<U>() -> Foo<U> { .. }
             // ```
             // figures out the concrete type with `U`, but the stored type is with `T`.
+            let opaque_type_key = OpaqueTypeKey { def_id, substs: opaque_defn.substs };
             let definition_ty = self.fcx.infer_opaque_definition_from_instantiation(
-                def_id,
-                opaque_defn.substs,
+                opaque_type_key,
                 instantiated_ty,
                 span,
             );
@@ -527,7 +527,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                         substs: opaque_defn.substs,
                     };
 
-                    let old = self.typeck_results.concrete_opaque_types.insert(def_id, new);
+                    let opaque_type_key = OpaqueTypeKey { def_id, substs: opaque_defn.substs };
+                    let old =
+                        self.typeck_results.concrete_opaque_types.insert(opaque_type_key, new);
                     if let Some(old) = old {
                         if old.concrete_type != definition_ty || old.substs != opaque_defn.substs {
                             span_bug!(
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 19c35ebd011..b53ef070a45 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -1,4 +1,5 @@
 use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::vec_map::VecMap;
 use rustc_errors::{Applicability, ErrorReported, StashKey};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -9,7 +10,9 @@ use rustc_hir::{HirId, Node};
 use rustc_middle::hir::map::Map;
 use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
 use rustc_middle::ty::util::IntTypeExt;
-use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{
+    self, DefIdTree, OpaqueTypeKey, ResolvedOpaqueTy, Ty, TyCtxt, TypeFoldable,
+};
 use rustc_span::symbol::Ident;
 use rustc_span::{Span, DUMMY_SP};
 
@@ -346,36 +349,36 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                 }
                 // Opaque types desugared from `impl Trait`.
                 ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: Some(owner), .. }) => {
-                    let concrete_ty = tcx
-                        .mir_borrowck(owner.expect_local())
-                        .concrete_opaque_types
-                        .get(&def_id.to_def_id())
-                        .map(|opaque| opaque.concrete_type)
-                        .unwrap_or_else(|| {
-                            tcx.sess.delay_span_bug(
-                                DUMMY_SP,
-                                &format!(
-                                    "owner {:?} has no opaque type for {:?} in its typeck results",
-                                    owner, def_id,
-                                ),
-                            );
-                            if let Some(ErrorReported) =
-                                tcx.typeck(owner.expect_local()).tainted_by_errors
-                            {
-                                // Some error in the
-                                // owner fn prevented us from populating
-                                // the `concrete_opaque_types` table.
-                                tcx.ty_error()
-                            } else {
-                                // We failed to resolve the opaque type or it
-                                // resolves to itself. Return the non-revealed
-                                // type, which should result in E0720.
-                                tcx.mk_opaque(
-                                    def_id.to_def_id(),
-                                    InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
-                                )
-                            }
-                        });
+                    let concrete_ty = find_concrete_ty_from_def_id(
+                        &tcx.mir_borrowck(owner.expect_local()).concrete_opaque_types,
+                        def_id.to_def_id(),
+                    )
+                    .map(|opaque| opaque.concrete_type)
+                    .unwrap_or_else(|| {
+                        tcx.sess.delay_span_bug(
+                            DUMMY_SP,
+                            &format!(
+                                "owner {:?} has no opaque type for {:?} in its typeck results",
+                                owner, def_id,
+                            ),
+                        );
+                        if let Some(ErrorReported) =
+                            tcx.typeck(owner.expect_local()).tainted_by_errors
+                        {
+                            // Some error in the
+                            // owner fn prevented us from populating
+                            // the `concrete_opaque_types` table.
+                            tcx.ty_error()
+                        } else {
+                            // We failed to resolve the opaque type or it
+                            // resolves to itself. Return the non-revealed
+                            // type, which should result in E0720.
+                            tcx.mk_opaque(
+                                def_id.to_def_id(),
+                                InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
+                            )
+                        }
+                    });
                     debug!("concrete_ty = {:?}", concrete_ty);
                     concrete_ty
                 }
@@ -515,7 +518,12 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
             }
             // Calling `mir_borrowck` can lead to cycle errors through
             // const-checking, avoid calling it if we don't have to.
-            if !self.tcx.typeck(def_id).concrete_opaque_types.contains_key(&self.def_id) {
+            if find_concrete_ty_from_def_id(
+                &self.tcx.typeck(def_id).concrete_opaque_types,
+                self.def_id,
+            )
+            .is_none()
+            {
                 debug!(
                     "find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`",
                     self.def_id, def_id,
@@ -523,7 +531,10 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
                 return;
             }
             // Use borrowck to get the type with unerased regions.
-            let ty = self.tcx.mir_borrowck(def_id).concrete_opaque_types.get(&self.def_id);
+            let ty = find_concrete_ty_from_def_id(
+                &self.tcx.mir_borrowck(def_id).concrete_opaque_types,
+                self.def_id,
+            );
             if let Some(ty::ResolvedOpaqueTy { concrete_type, substs }) = ty {
                 debug!(
                     "find_opaque_ty_constraints: found constraint for `{:?}` at `{:?}`: {:?}",
@@ -697,32 +708,31 @@ fn let_position_impl_trait_type(tcx: TyCtxt<'_>, opaque_ty_id: LocalDefId) -> Ty
     let opaque_ty_def_id = opaque_ty_id.to_def_id();
 
     let owner_typeck_results = tcx.typeck(scope_def_id);
-    let concrete_ty = owner_typeck_results
-        .concrete_opaque_types
-        .get(&opaque_ty_def_id)
-        .map(|opaque| opaque.concrete_type)
-        .unwrap_or_else(|| {
-            tcx.sess.delay_span_bug(
-                DUMMY_SP,
-                &format!(
-                    "owner {:?} has no opaque type for {:?} in its typeck results",
-                    scope_def_id, opaque_ty_id
-                ),
-            );
-            if let Some(ErrorReported) = owner_typeck_results.tainted_by_errors {
-                // Some error in the owner fn prevented us from populating the
-                // `concrete_opaque_types` table.
-                tcx.ty_error()
-            } else {
-                // We failed to resolve the opaque type or it resolves to
-                // itself. Return the non-revealed type, which should result in
-                // E0720.
-                tcx.mk_opaque(
-                    opaque_ty_def_id,
-                    InternalSubsts::identity_for_item(tcx, opaque_ty_def_id),
-                )
-            }
-        });
+    let concrete_ty =
+        find_concrete_ty_from_def_id(&owner_typeck_results.concrete_opaque_types, opaque_ty_def_id)
+            .map(|opaque| opaque.concrete_type)
+            .unwrap_or_else(|| {
+                tcx.sess.delay_span_bug(
+                    DUMMY_SP,
+                    &format!(
+                        "owner {:?} has no opaque type for {:?} in its typeck results",
+                        scope_def_id, opaque_ty_id
+                    ),
+                );
+                if let Some(ErrorReported) = owner_typeck_results.tainted_by_errors {
+                    // Some error in the owner fn prevented us from populating the
+                    // `concrete_opaque_types` table.
+                    tcx.ty_error()
+                } else {
+                    // We failed to resolve the opaque type or it resolves to
+                    // itself. Return the non-revealed type, which should result in
+                    // E0720.
+                    tcx.mk_opaque(
+                        opaque_ty_def_id,
+                        InternalSubsts::identity_for_item(tcx, opaque_ty_def_id),
+                    )
+                }
+            });
     debug!("concrete_ty = {:?}", concrete_ty);
     if concrete_ty.has_erased_regions() {
         // FIXME(impl_trait_in_bindings) Handle this case.
@@ -796,3 +806,13 @@ fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) {
         .emit();
     }
 }
+
+fn find_concrete_ty_from_def_id<'tcx>(
+    concrete_opaque_types: &'tcx VecMap<OpaqueTypeKey<'tcx>, ResolvedOpaqueTy<'tcx>>,
+    def_id: DefId,
+) -> Option<&'tcx ResolvedOpaqueTy<'tcx>> {
+    concrete_opaque_types
+        .iter()
+        .find(|(opaque_type_key, _)| opaque_type_key.def_id == def_id)
+        .map(|(_, resolved_opaque_ty)| resolved_opaque_ty)
+}