]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_infer/src/infer/lattice.rs
Rollup merge of #95344 - jyn514:better-debug-output, r=camelid
[rust.git] / compiler / rustc_infer / src / infer / lattice.rs
index 32affd6a14e1cf0038441feb1fffc9eccc9cdc1c..1e3293efad649be1d3e490353ed7b37fe19d979a 100644 (file)
@@ -20,7 +20,7 @@
 use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use super::InferCtxt;
 
-use crate::traits::ObligationCause;
+use crate::traits::{ObligationCause, PredicateObligation};
 use rustc_middle::ty::relate::{RelateResult, TypeRelation};
 use rustc_middle::ty::TyVar;
 use rustc_middle::ty::{self, Ty};
@@ -35,6 +35,10 @@ pub trait LatticeDir<'f, 'tcx>: TypeRelation<'tcx> {
 
     fn cause(&self) -> &ObligationCause<'tcx>;
 
+    fn add_obligations(&mut self, obligations: Vec<PredicateObligation<'tcx>>);
+
+    fn define_opaque_types(&self) -> bool;
+
     // Relates the type `v` to `a` and `b` such that `v` represents
     // the LUB/GLB of `a` and `b` as appropriate.
     //
@@ -45,6 +49,7 @@ pub trait LatticeDir<'f, 'tcx>: TypeRelation<'tcx> {
 }
 
 /// Relates two types using a given lattice.
+#[instrument(skip(this), level = "debug")]
 pub fn super_lattice_tys<'a, 'tcx: 'a, L>(
     this: &mut L,
     a: Ty<'tcx>,
@@ -53,15 +58,17 @@ pub fn super_lattice_tys<'a, 'tcx: 'a, L>(
 where
     L: LatticeDir<'a, 'tcx>,
 {
-    debug!("{}.lattice_tys({:?}, {:?})", this.tag(), a, b);
+    debug!("{}", this.tag());
 
     if a == b {
         return Ok(a);
     }
 
     let infcx = this.infcx();
+
     let a = infcx.inner.borrow_mut().type_variables().replace_if_possible(a);
     let b = infcx.inner.borrow_mut().type_variables().replace_if_possible(b);
+
     match (a.kind(), b.kind()) {
         // If one side is known to be a variable and one is not,
         // create a variable (`v`) to represent the LUB. Make sure to
@@ -76,7 +83,7 @@ pub fn super_lattice_tys<'a, 'tcx: 'a, L>(
         // But if we did in reverse order, we would create a `v <:
         // LHS` (or vice versa) constraint and then instantiate
         // `v`. This would require further processing to achieve same
-        // end-result; in partiular, this screws up some of the logic
+        // end-result; in particular, this screws up some of the logic
         // in coercion, which expects LUB to figure out that the LHS
         // is (e.g.) `Box<i32>`. A more obvious solution might be to
         // iterate on the subtype obligations that are returned, but I
@@ -98,6 +105,20 @@ pub fn super_lattice_tys<'a, 'tcx: 'a, L>(
             Ok(v)
         }
 
+        (&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => {
+            infcx.super_combine_tys(this, a, b)
+        }
+        (&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..))
+            if this.define_opaque_types() && did.is_local() =>
+        {
+            this.add_obligations(
+                infcx
+                    .handle_opaque_type(a, b, this.a_is_expected(), this.cause(), this.param_env())?
+                    .obligations,
+            );
+            Ok(a)
+        }
+
         _ => infcx.super_combine_tys(this, a, b),
     }
 }