]> git.lizzy.rs Git - rust.git/commitdiff
Store the `DefId` of the currently typechecked item in `InferCtxt`
authorOli Scherer <github35764891676564198441@oli-obk.de>
Thu, 29 Jul 2021 15:59:59 +0000 (15:59 +0000)
committerOli Scherer <github35764891676564198441@oli-obk.de>
Fri, 6 Aug 2021 10:39:23 +0000 (10:39 +0000)
This allows opaque type inference to check for defining uses without having to pass down that def id via function arguments to every method that could possibly cause an opaque type to be compared with a concrete type

compiler/rustc_infer/src/infer/mod.rs
compiler/rustc_mir/src/borrow_check/mod.rs
compiler/rustc_mir/src/borrow_check/type_check/mod.rs
compiler/rustc_trait_selection/src/opaque_types.rs
compiler/rustc_typeck/src/check/_match.rs
compiler/rustc_typeck/src/check/check.rs
compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs

index 62bfe03427e1c0d46ee9ebca3d47c36ab44181c6..e3836f667a9e93562cf8f1a528cd8edbb6334a84 100644 (file)
@@ -9,6 +9,7 @@
 
 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;
@@ -292,6 +293,10 @@ pub fn unwrap_region_constraints(&mut self) -> RegionConstraintCollector<'_, 'tc
 pub struct InferCtxt<'a, 'tcx> {
     pub tcx: TyCtxt<'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,
+
     /// During type-checking/inference of a body, `in_progress_typeck_results`
     /// contains a reference to the typeck results being built up, which are
     /// used for reading closure kinds/signatures as they are inferred,
@@ -550,6 +555,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 pub struct InferCtxtBuilder<'tcx> {
     tcx: TyCtxt<'tcx>,
     fresh_typeck_results: Option<RefCell<ty::TypeckResults<'tcx>>>,
+    defining_use_anchor: LocalDefId,
 }
 
 pub trait TyCtxtInferExt<'tcx> {
@@ -558,15 +564,27 @@ pub trait TyCtxtInferExt<'tcx> {
 
 impl TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
     fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
-        InferCtxtBuilder { tcx: self, fresh_typeck_results: None }
+        InferCtxtBuilder {
+            tcx: self,
+            defining_use_anchor: CRATE_DEF_ID,
+            fresh_typeck_results: None,
+        }
     }
 }
 
 impl<'tcx> InferCtxtBuilder<'tcx> {
     /// Used only by `rustc_typeck` during body type-checking/inference,
     /// will initialize `in_progress_typeck_results` with fresh `TypeckResults`.
+    /// Will also change the scope for opaque type defining use checks to the given owner.
     pub fn with_fresh_in_progress_typeck_results(mut self, table_owner: LocalDefId) -> Self {
         self.fresh_typeck_results = Some(RefCell::new(ty::TypeckResults::new(table_owner)));
+        self.with_opaque_type_inference(table_owner)
+    }
+
+    /// Whenever the `InferCtxt` should be able to handle defining uses of opaque types,
+    /// you need to call this function. Otherwise the opaque type will be treated opaquely.
+    pub fn with_opaque_type_inference(mut self, defining_use_anchor: LocalDefId) -> Self {
+        self.defining_use_anchor = defining_use_anchor;
         self
     }
 
@@ -594,10 +612,11 @@ pub fn enter_with_canonical<T, R>(
     }
 
     pub fn enter<R>(&mut self, f: impl for<'a> FnOnce(InferCtxt<'a, 'tcx>) -> R) -> R {
-        let InferCtxtBuilder { tcx, ref fresh_typeck_results } = *self;
+        let InferCtxtBuilder { tcx, defining_use_anchor, ref fresh_typeck_results } = *self;
         let in_progress_typeck_results = fresh_typeck_results.as_ref();
         f(InferCtxt {
             tcx,
+            defining_use_anchor,
             in_progress_typeck_results,
             inner: RefCell::new(InferCtxtInner::new()),
             lexical_region_resolutions: RefCell::new(None),
index 36eb8a4baa8308f1f7d13a8c81c8f64cb79d57d2..2bfa51f27bbb610ad932d222da084a989cc5ac7f 100644 (file)
@@ -105,7 +105,7 @@ fn mir_borrowck<'tcx>(
     let (input_body, promoted) = tcx.mir_promoted(def);
     debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id()));
 
-    let opt_closure_req = tcx.infer_ctxt().enter(|infcx| {
+    let opt_closure_req = tcx.infer_ctxt().with_opaque_type_inference(def.did).enter(|infcx| {
         let input_body: &Body<'_> = &input_body.borrow();
         let promoted: &IndexVec<_, _> = &promoted.borrow();
         do_mir_borrowck(&infcx, input_body, promoted)
index d4edd8da7cc41759e29b0a6148f48108b1ad3c77..f69d08a6d594231163296fac607a42bd41da390d 100644 (file)
@@ -1305,7 +1305,6 @@ fn eq_opaque_type_and_type(
                     // (Note that the key of the map is both the def-id of `Foo` along with
                     // any generic parameters.)
                     let output_ty = obligations.add(infcx.instantiate_opaque_types(
-                        mir_def_id,
                         dummy_body_id,
                         param_env,
                         anon_ty,
index 70360f176bf6bac0b1dad2d6a1a73d828002866a..c24e738a7df030f8c832690c73cd2cb26f6cbc0c 100644 (file)
@@ -32,7 +32,6 @@ pub enum GenerateMemberConstraints {
 pub trait InferCtxtExt<'tcx> {
     fn instantiate_opaque_types<T: TypeFoldable<'tcx>>(
         &self,
-        parent_def_id: LocalDefId,
         body_id: hir::HirId,
         param_env: ty::ParamEnv<'tcx>,
         value: T,
@@ -94,25 +93,18 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
     /// - `value_span` -- the span where the value came from, used in error reporting
     fn instantiate_opaque_types<T: TypeFoldable<'tcx>>(
         &self,
-        parent_def_id: LocalDefId,
         body_id: hir::HirId,
         param_env: ty::ParamEnv<'tcx>,
         value: T,
         value_span: Span,
     ) -> InferOk<'tcx, T> {
         debug!(
-            "instantiate_opaque_types(value={:?}, parent_def_id={:?}, body_id={:?}, \
+            "instantiate_opaque_types(value={:?}, body_id={:?}, \
              param_env={:?}, value_span={:?})",
-            value, parent_def_id, body_id, param_env, value_span,
+            value, body_id, param_env, value_span,
         );
-        let mut instantiator = Instantiator {
-            infcx: self,
-            parent_def_id,
-            body_id,
-            param_env,
-            value_span,
-            obligations: vec![],
-        };
+        let mut instantiator =
+            Instantiator { infcx: self, body_id, param_env, value_span, obligations: vec![] };
         let value = instantiator.instantiate_opaque_types_in_map(value);
         InferOk { value, obligations: instantiator.obligations }
     }
@@ -857,7 +849,6 @@ fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
 
 struct Instantiator<'a, 'tcx> {
     infcx: &'a InferCtxt<'a, 'tcx>,
-    parent_def_id: LocalDefId,
     body_id: hir::HirId,
     param_env: ty::ParamEnv<'tcx>,
     value_span: Span,
@@ -910,7 +901,7 @@ fn instantiate_opaque_types_in_map<T: TypeFoldable<'tcx>>(&mut self, value: T) -
                     // ```
                     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.parent_def_id;
+                        let parent_def_id = self.infcx.defining_use_anchor;
                         let def_scope_default = || {
                             let opaque_parent_hir_id = tcx.hir().get_parent_item(opaque_hir_id);
                             parent_def_id == tcx.hir().local_def_id(opaque_parent_hir_id)
@@ -922,14 +913,14 @@ fn instantiate_opaque_types_in_map<T: TypeFoldable<'tcx>>(&mut self, value: T) -
                                     impl_trait_fn: Some(parent),
                                     origin,
                                     ..
-                                }) => (parent == self.parent_def_id.to_def_id(), origin),
+                                }) => (parent == parent_def_id.to_def_id(), origin),
                                 // Named `type Foo = impl Bar;`
                                 hir::ItemKind::OpaqueTy(hir::OpaqueTy {
                                     impl_trait_fn: None,
                                     origin,
                                     ..
                                 }) => (
-                                    may_define_opaque_type(tcx, self.parent_def_id, opaque_hir_id),
+                                    may_define_opaque_type(tcx, parent_def_id, opaque_hir_id),
                                     origin,
                                 ),
                                 _ => (def_scope_default(), hir::OpaqueTyOrigin::TyAlias),
index db881745516798e3ef122c77c76f567c51802354..10c3a97e73a5af46123d9446b320a1532007fdbc 100644 (file)
@@ -593,11 +593,11 @@ pub(crate) fn opt_suggest_box_span(
         orig_expected: Expectation<'tcx>,
     ) -> Option<Span> {
         match (orig_expected, self.ret_coercion_impl_trait.map(|ty| (self.body_id.owner, ty))) {
-            (Expectation::ExpectHasType(expected), Some((id, ty)))
+            (Expectation::ExpectHasType(expected), Some((_id, ty)))
                 if self.in_tail_expr && self.can_coerce(outer_ty, expected) =>
             {
                 let impl_trait_ret_ty =
-                    self.infcx.instantiate_opaque_types(id, self.body_id, self.param_env, ty, span);
+                    self.infcx.instantiate_opaque_types(self.body_id, self.param_env, ty, span);
                 assert!(
                     impl_trait_ret_ty.obligations.is_empty(),
                     "we should never get new obligations here"
index 2496747c0619d3e87719b3353d7eea396ba82da9..8b5b7e3e52c80d0d9cd72a8c029ab4308e3ef4c3 100644 (file)
@@ -95,7 +95,7 @@ pub(super) fn check_fn<'a, 'tcx>(
     let declared_ret_ty = fn_sig.output();
 
     let revealed_ret_ty =
-        fcx.instantiate_opaque_types_from_value(fn_id, declared_ret_ty, decl.output.span());
+        fcx.instantiate_opaque_types_from_value(declared_ret_ty, decl.output.span());
     debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
     fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
     fcx.ret_type_span = Some(decl.output.span());
@@ -651,7 +651,7 @@ fn check_opaque_meets_bounds<'tcx>(
         let misc_cause = traits::ObligationCause::misc(span, hir_id);
 
         let _ = inh.register_infer_ok_obligations(
-            infcx.instantiate_opaque_types(def_id, hir_id, param_env, opaque_ty, span),
+            infcx.instantiate_opaque_types(hir_id, param_env, opaque_ty, span),
         );
 
         let opaque_type_map = infcx.inner.borrow().opaque_types.clone();
index ba235c142692d389894181fcfbd737086a24424e..b84a79b768c9a32223fa1c739685d54c372c83e8 100644 (file)
@@ -362,20 +362,13 @@ pub(in super::super) fn instantiate_bounds(
     /// Replaces the opaque types from the given value with type variables,
     /// and records the `OpaqueTypeMap` for later use during writeback. See
     /// `InferCtxt::instantiate_opaque_types` for more details.
+    #[instrument(skip(self, value_span), level = "debug")]
     pub(in super::super) fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
         &self,
-        parent_id: hir::HirId,
         value: T,
         value_span: Span,
     ) -> T {
-        let parent_def_id = self.tcx.hir().local_def_id(parent_id);
-        debug!(
-            "instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
-            parent_def_id, value
-        );
-
         self.register_infer_ok_obligations(self.instantiate_opaque_types(
-            parent_def_id,
             self.body_id,
             self.param_env,
             value,