about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-01-14 07:47:31 +0100
committerGitHub <noreply@github.com>2022-01-14 07:47:31 +0100
commitf13e871ac561b54ddeac2b6173b1905fb4b20138 (patch)
treeae5e0158a4d9061bc46684caf098b3ef994d3b2b
parentf312a5e610d47601e9a3da828002f5e1ffeb272a (diff)
parent956db072a877284e8d057dae717cf8253505a4ff (diff)
downloadrust-f13e871ac561b54ddeac2b6173b1905fb4b20138.tar.gz
rust-f13e871ac561b54ddeac2b6173b1905fb4b20138.zip
Rollup merge of #92045 - oli-obk:cleanup, r=petrochenkov
Don't fall back to crate-level opaque type definitions.

That would just hide bugs, as it works accidentally if the opaque type is defined at the crate level.

Only works after #90948 which worked by accident for our entire test suite.
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs18
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs50
2 files changed, 36 insertions, 32 deletions
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 04e04e297cd..d3664e53447 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -10,7 +10,6 @@ pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog};
 
 use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine};
 
-use hir::def_id::CRATE_DEF_ID;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::undo_log::Rollback;
@@ -291,7 +290,12 @@ pub struct InferCtxt<'a, 'tcx> {
 
     /// The `DefId` of the item in whose context we are performing inference or typeck.
     /// It is used to check whether an opaque type use is a defining use.
-    pub defining_use_anchor: LocalDefId,
+    ///
+    /// If it is `None`, we can't resolve opaque types here and need to bubble up
+    /// the obligation. This frequently happens for
+    /// short lived InferCtxt within queries. The opaque type obligations are forwarded
+    /// to the outside until the end up in an `InferCtxt` for typeck or borrowck.
+    pub defining_use_anchor: Option<LocalDefId>,
 
     /// During type-checking/inference of a body, `in_progress_typeck_results`
     /// contains a reference to the typeck results being built up, which are
@@ -547,7 +551,7 @@ impl<'tcx> fmt::Display for FixupError<'tcx> {
 pub struct InferCtxtBuilder<'tcx> {
     tcx: TyCtxt<'tcx>,
     fresh_typeck_results: Option<RefCell<ty::TypeckResults<'tcx>>>,
-    defining_use_anchor: LocalDefId,
+    defining_use_anchor: Option<LocalDefId>,
 }
 
 pub trait TyCtxtInferExt<'tcx> {
@@ -556,11 +560,7 @@ pub trait TyCtxtInferExt<'tcx> {
 
 impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
     fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
-        InferCtxtBuilder {
-            tcx: self,
-            defining_use_anchor: CRATE_DEF_ID,
-            fresh_typeck_results: None,
-        }
+        InferCtxtBuilder { tcx: self, defining_use_anchor: None, fresh_typeck_results: None }
     }
 }
 
@@ -580,7 +580,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
     /// (via `with_fresh_in_progress_typeck_results`) and for the inference context used
     /// in mir borrowck.
     pub fn with_opaque_type_inference(mut self, defining_use_anchor: LocalDefId) -> Self {
-        self.defining_use_anchor = defining_use_anchor;
+        self.defining_use_anchor = Some(defining_use_anchor);
         self
     }
 
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index d5e65705b28..04b1a42e5be 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -328,6 +328,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             },
         });
     }
+
+    fn opaque_type_origin(&self, def_id: LocalDefId) -> Option<hir::OpaqueTyOrigin> {
+        let tcx = self.tcx;
+        let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
+        let parent_def_id = self.defining_use_anchor?;
+        let item_kind = &tcx.hir().expect_item(def_id).kind;
+        let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, ..  }) = item_kind else {
+            span_bug!(
+                tcx.def_span(def_id),
+                "weird opaque type: {:#?}",
+                item_kind
+            )
+        };
+        let in_definition_scope = match *origin {
+            // Async `impl Trait`
+            hir::OpaqueTyOrigin::AsyncFn(parent) => parent == parent_def_id,
+            // Anonymous `impl Trait`
+            hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
+            // Named `type Foo = impl Bar;`
+            hir::OpaqueTyOrigin::TyAlias => {
+                may_define_opaque_type(tcx, parent_def_id, opaque_hir_id)
+            }
+        };
+        in_definition_scope.then_some(*origin)
+    }
 }
 
 // Visitor that requires that (almost) all regions in the type visited outlive
@@ -459,31 +484,10 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
                     // }
                     // ```
                     if let Some(def_id) = def_id.as_local() {
-                        let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
-                        let parent_def_id = self.infcx.defining_use_anchor;
-                        let item_kind = &tcx.hir().expect_item(def_id).kind;
-                        let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, ..  }) = item_kind else {
-                            span_bug!(
-                                self.value_span,
-                                "weird opaque type: {:#?}, {:#?}",
-                                ty.kind(),
-                                item_kind
-                            )
-                        };
-                        let in_definition_scope = match *origin {
-                            // Async `impl Trait`
-                            hir::OpaqueTyOrigin::AsyncFn(parent) => parent == parent_def_id,
-                            // Anonymous `impl Trait`
-                            hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
-                            // Named `type Foo = impl Bar;`
-                            hir::OpaqueTyOrigin::TyAlias => {
-                                may_define_opaque_type(tcx, parent_def_id, opaque_hir_id)
-                            }
-                        };
-                        if in_definition_scope {
+                        if let Some(origin) = self.infcx.opaque_type_origin(def_id) {
                             let opaque_type_key =
                                 OpaqueTypeKey { def_id: def_id.to_def_id(), substs };
-                            return self.fold_opaque_ty(ty, opaque_type_key, *origin);
+                            return self.fold_opaque_ty(ty, opaque_type_key, origin);
                         }
 
                         debug!(