about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2020-11-20 05:40:33 -0500
committerMark Rousskov <mark.simulacrum@gmail.com>2021-08-19 17:28:24 -0400
commit7e0ae7d89bcbf5174ab2d5198c438cfd0bebd4e8 (patch)
treeb86b0584bd5a1ef7b34e468f08cc4b8113c23c93
parentc1b4824800597f7ce9831ae27dc994badabc40e3 (diff)
downloadrust-7e0ae7d89bcbf5174ab2d5198c438cfd0bebd4e8.tar.gz
rust-7e0ae7d89bcbf5174ab2d5198c438cfd0bebd4e8.zip
introduce a `Diverging` enum instead of a bool
-rw-r--r--compiler/rustc_infer/src/infer/combine.rs6
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs20
-rw-r--r--compiler/rustc_infer/src/infer/nll_relate/mod.rs4
-rw-r--r--compiler/rustc_infer/src/infer/type_variable.rs12
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs97
5 files changed, 78 insertions, 61 deletions
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs
index 3a11b5a2144..79dc1c4bee6 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/combine.rs
@@ -22,7 +22,6 @@
 // is also useful to track which value is the "expected" value in
 // terms of error reporting.
 
-use super::equate::Equate;
 use super::glb::Glb;
 use super::lub::Lub;
 use super::sub::Sub;
@@ -30,6 +29,7 @@ use super::type_variable::TypeVariableValue;
 use super::unify_key::replace_if_possible;
 use super::unify_key::{ConstVarValue, ConstVariableValue};
 use super::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
+use super::{equate::Equate, type_variable::Diverging};
 use super::{InferCtxt, MiscVariable, TypeTrace};
 
 use crate::traits::{Obligation, PredicateObligations};
@@ -643,7 +643,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
                                 .inner
                                 .borrow_mut()
                                 .type_variables()
-                                .new_var(self.for_universe, false, origin);
+                                .new_var(self.for_universe, Diverging::NotDiverging, origin);
                             let u = self.tcx().mk_ty_var(new_var_id);
                             debug!("generalize: replacing original vid={:?} with new={:?}", vid, u);
                             Ok(u)
@@ -881,7 +881,7 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
                             *self.infcx.inner.borrow_mut().type_variables().var_origin(vid);
                         let new_var_id = self.infcx.inner.borrow_mut().type_variables().new_var(
                             self.for_universe,
-                            false,
+                            Diverging::NotDiverging,
                             origin,
                         );
                         let u = self.tcx().mk_ty_var(new_var_id);
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 9b9ded5c6ba..26bee3596e3 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -46,7 +46,7 @@ use self::region_constraints::{GenericKind, RegionConstraintData, VarInfos, Veri
 use self::region_constraints::{
     RegionConstraintCollector, RegionConstraintStorage, RegionSnapshot,
 };
-use self::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use self::type_variable::{Diverging, TypeVariableOrigin, TypeVariableOriginKind};
 
 pub mod at;
 pub mod canonical;
@@ -679,10 +679,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         t.fold_with(&mut self.freshener())
     }
 
-    pub fn type_var_diverges(&'a self, ty: Ty<'_>) -> bool {
+    pub fn type_var_diverges(&'a self, ty: Ty<'_>) -> Diverging {
         match *ty.kind() {
             ty::Infer(ty::TyVar(vid)) => self.inner.borrow_mut().type_variables().var_diverges(vid),
-            _ => false,
+            _ => Diverging::NotDiverging,
         }
     }
 
@@ -1020,12 +1020,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         })
     }
 
-    pub fn next_ty_var_id(&self, diverging: bool, origin: TypeVariableOrigin) -> TyVid {
+    pub fn next_ty_var_id(&self, diverging: Diverging, origin: TypeVariableOrigin) -> TyVid {
         self.inner.borrow_mut().type_variables().new_var(self.universe(), diverging, origin)
     }
 
     pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
-        self.tcx.mk_ty_var(self.next_ty_var_id(false, origin))
+        self.tcx.mk_ty_var(self.next_ty_var_id(Diverging::NotDiverging, origin))
     }
 
     pub fn next_ty_var_in_universe(
@@ -1033,12 +1033,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         origin: TypeVariableOrigin,
         universe: ty::UniverseIndex,
     ) -> Ty<'tcx> {
-        let vid = self.inner.borrow_mut().type_variables().new_var(universe, false, origin);
+        let vid = self.inner.borrow_mut().type_variables().new_var(
+            universe,
+            Diverging::NotDiverging,
+            origin,
+        );
         self.tcx.mk_ty_var(vid)
     }
 
     pub fn next_diverging_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
-        self.tcx.mk_ty_var(self.next_ty_var_id(true, origin))
+        self.tcx.mk_ty_var(self.next_ty_var_id(Diverging::Diverges, origin))
     }
 
     pub fn next_const_var(
@@ -1152,7 +1156,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 // as the substitutions for the default, `(T, U)`.
                 let ty_var_id = self.inner.borrow_mut().type_variables().new_var(
                     self.universe(),
-                    false,
+                    Diverging::NotDiverging,
                     TypeVariableOrigin {
                         kind: TypeVariableOriginKind::TypeParameterDefinition(
                             param.name,
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index 20be06adfd0..261c3471a98 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -22,6 +22,7 @@
 //!   constituents)
 
 use crate::infer::combine::ConstEquateRelation;
+use crate::infer::type_variable::Diverging;
 use crate::infer::InferCtxt;
 use crate::infer::{ConstVarValue, ConstVariableValue};
 use rustc_data_structures::fx::FxHashMap;
@@ -920,7 +921,8 @@ where
                             // Replacing with a new variable in the universe `self.universe`,
                             // it will be unified later with the original type variable in
                             // the universe `_universe`.
-                            let new_var_id = variables.new_var(self.universe, false, origin);
+                            let new_var_id =
+                                variables.new_var(self.universe, Diverging::NotDiverging, origin);
 
                             let u = self.tcx().mk_ty_var(new_var_id);
                             debug!("generalize: replacing original vid={:?} with new={:?}", vid, u);
diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs
index 13b78b26af4..42e2a0c8586 100644
--- a/compiler/rustc_infer/src/infer/type_variable.rs
+++ b/compiler/rustc_infer/src/infer/type_variable.rs
@@ -119,7 +119,13 @@ pub enum TypeVariableOriginKind {
 
 pub(crate) struct TypeVariableData {
     origin: TypeVariableOrigin,
-    diverging: bool,
+    diverging: Diverging,
+}
+
+#[derive(Copy, Clone, Debug)]
+pub enum Diverging {
+    NotDiverging,
+    Diverges,
 }
 
 #[derive(Copy, Clone, Debug)]
@@ -173,7 +179,7 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
     ///
     /// Note that this function does not return care whether
     /// `vid` has been unified with something else or not.
-    pub fn var_diverges(&self, vid: ty::TyVid) -> bool {
+    pub fn var_diverges(&self, vid: ty::TyVid) -> Diverging {
         self.storage.values.get(vid.index as usize).diverging
     }
 
@@ -238,7 +244,7 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
     pub fn new_var(
         &mut self,
         universe: ty::UniverseIndex,
-        diverging: bool,
+        diverging: Diverging,
         origin: TypeVariableOrigin,
     ) -> ty::TyVid {
         let eq_key = self.eq_relations().new_key(TypeVariableValue::Unknown { universe });
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index c13901ae8be..9405b64260c 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -17,6 +17,7 @@ use rustc_hir::lang_items::LangItem;
 use rustc_hir::{ExprKind, GenericArg, Node, QPath, TyKind};
 use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
+use rustc_infer::infer::type_variable::Diverging;
 use rustc_infer::infer::{InferOk, InferResult};
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
 use rustc_middle::ty::fold::TypeFoldable;
@@ -656,56 +657,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             _ if self.is_tainted_by_errors() => self.tcx().ty_error(),
             UnconstrainedInt => self.tcx.types.i32,
             UnconstrainedFloat => self.tcx.types.f64,
-            Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
-            Neither => {
-                // This type variable was created from the instantiation of an opaque
-                // type. The fact that we're attempting to perform fallback for it
-                // means that the function neither constrained it to a concrete
-                // type, nor to the opaque type itself.
-                //
-                // For example, in this code:
-                //
-                //```
-                // type MyType = impl Copy;
-                // fn defining_use() -> MyType { true }
-                // fn other_use() -> MyType { defining_use() }
-                // ```
-                //
-                // `defining_use` will constrain the instantiated inference
-                // variable to `bool`, while `other_use` will constrain
-                // the instantiated inference variable to `MyType`.
-                //
-                // When we process opaque types during writeback, we
-                // will handle cases like `other_use`, and not count
-                // them as defining usages
-                //
-                // However, we also need to handle cases like this:
-                //
-                // ```rust
-                // pub type Foo = impl Copy;
-                // fn produce() -> Option<Foo> {
-                //     None
-                //  }
-                //  ```
-                //
-                // In the above snippet, the inference variable created by
-                // instantiating `Option<Foo>` will be completely unconstrained.
-                // We treat this as a non-defining use by making the inference
-                // variable fall back to the opaque type itself.
-                if let FallbackMode::All = mode {
-                    if let Some(opaque_ty) = self.infcx.inner.borrow().opaque_types_vars.get(ty) {
-                        debug!(
-                            "fallback_if_possible: falling back opaque type var {:?} to {:?}",
-                            ty, opaque_ty
-                        );
-                        *opaque_ty
+            Neither => match self.type_var_diverges(ty) {
+                Diverging::Diverges => self.tcx.mk_diverging_default(),
+
+                Diverging::NotDiverging => {
+                    // This type variable was created from the instantiation of an opaque
+                    // type. The fact that we're attempting to perform fallback for it
+                    // means that the function neither constrained it to a concrete
+                    // type, nor to the opaque type itself.
+                    //
+                    // For example, in this code:
+                    //
+                    //```
+                    // type MyType = impl Copy;
+                    // fn defining_use() -> MyType { true }
+                    // fn other_use() -> MyType { defining_use() }
+                    // ```
+                    //
+                    // `defining_use` will constrain the instantiated inference
+                    // variable to `bool`, while `other_use` will constrain
+                    // the instantiated inference variable to `MyType`.
+                    //
+                    // When we process opaque types during writeback, we
+                    // will handle cases like `other_use`, and not count
+                    // them as defining usages
+                    //
+                    // However, we also need to handle cases like this:
+                    //
+                    // ```rust
+                    // pub type Foo = impl Copy;
+                    // fn produce() -> Option<Foo> {
+                    //     None
+                    //  }
+                    //  ```
+                    //
+                    // In the above snippet, the inference variable created by
+                    // instantiating `Option<Foo>` will be completely unconstrained.
+                    // We treat this as a non-defining use by making the inference
+                    // variable fall back to the opaque type itself.
+                    if let FallbackMode::All = mode {
+                        if let Some(opaque_ty) = self.infcx.inner.borrow().opaque_types_vars.get(ty)
+                        {
+                            debug!(
+                                "fallback_if_possible: falling back opaque type var {:?} to {:?}",
+                                ty, opaque_ty
+                            );
+                            *opaque_ty
+                        } else {
+                            return false;
+                        }
                     } else {
                         return false;
                     }
-                } else {
-                    return false;
                 }
-            }
+            },
         };
         debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
         self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);