]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
implement tainted_by_errors in mir borrowck
[rust.git] / compiler / rustc_borrowck / src / diagnostics / bound_region_errors.rs
index 07289d68e2de38b7d618a66f4df5af02432df486..ac9950241bfe3a7d2b558fcf5791b2266ea82a61 100644 (file)
@@ -2,13 +2,9 @@
 use rustc_infer::infer::canonical::Canonical;
 use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError;
 use rustc_infer::infer::region_constraints::Constraint;
-use rustc_infer::infer::region_constraints::RegionConstraintData;
-use rustc_infer::infer::RegionVariableOrigin;
 use rustc_infer::infer::{InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt as _};
 use rustc_infer::traits::{Normalized, ObligationCause, TraitEngine, TraitEngineExt};
 use rustc_middle::ty::error::TypeError;
-use rustc_middle::ty::RegionVid;
-use rustc_middle::ty::UniverseIndex;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc_span::Span;
 use rustc_trait_selection::traits::query::type_op;
@@ -59,7 +55,7 @@ impl<'tcx> UniverseInfo<'tcx> {
                     found,
                     TypeError::RegionsPlaceholderMismatch,
                 );
-                err.buffer(&mut mbcx.errors_buffer);
+                mbcx.buffer_error(err);
             }
             UniverseInfoInner::TypeOp(ref type_op_info) => {
                 type_op_info.report_error(mbcx, placeholder, error_element, cause);
@@ -68,11 +64,9 @@ impl<'tcx> UniverseInfo<'tcx> {
                 // FIXME: This error message isn't great, but it doesn't show
                 // up in the existing UI tests. Consider investigating this
                 // some more.
-                mbcx.infcx
-                    .tcx
-                    .sess
-                    .struct_span_err(cause.span, "higher-ranked subtype error")
-                    .buffer(&mut mbcx.errors_buffer);
+                mbcx.buffer_error(
+                    mbcx.infcx.tcx.sess.struct_span_err(cause.span, "higher-ranked subtype error"),
+                );
             }
         }
     }
@@ -82,15 +76,6 @@ impl<'tcx> UniverseInfo<'tcx> {
     fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx>;
 }
 
-impl<'tcx> ToUniverseInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
-    fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
-        UniverseInfo(UniverseInfoInner::TypeOp(Rc::new(crate::type_check::InstantiateOpaqueType {
-            base_universe: Some(base_universe),
-            ..self
-        })))
-    }
-}
-
 impl<'tcx> ToUniverseInfo<'tcx>
     for Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::prove_predicate::ProvePredicate<'tcx>>>
 {
@@ -131,12 +116,6 @@ fn to_universe_info(self, _base_universe: ty::UniverseIndex) -> UniverseInfo<'tc
     }
 }
 
-impl<'tcx> ToUniverseInfo<'tcx> for ! {
-    fn to_universe_info(self, _base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
-        self
-    }
-}
-
 #[allow(unused_lifetimes)]
 trait TypeOpInfo<'tcx> {
     /// Returns an error to be reported if rerunning the type op fails to
@@ -147,7 +126,7 @@ trait TypeOpInfo<'tcx> {
 
     fn nice_error(
         &self,
-        mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         cause: ObligationCause<'tcx>,
         placeholder_region: ty::Region<'tcx>,
         error_region: Option<ty::Region<'tcx>>,
@@ -168,7 +147,7 @@ fn report_error(
         {
             adjusted
         } else {
-            self.fallback_error(tcx, cause.span).buffer(&mut mbcx.errors_buffer);
+            mbcx.buffer_error(self.fallback_error(tcx, cause.span));
             return;
         };
 
@@ -194,12 +173,12 @@ fn report_error(
         debug!(?placeholder_region);
 
         let span = cause.span;
-        let nice_error = self.nice_error(mbcx, cause, placeholder_region, error_region);
+        let nice_error = self.nice_error(tcx, cause, placeholder_region, error_region);
 
         if let Some(nice_error) = nice_error {
-            nice_error.buffer(&mut mbcx.errors_buffer);
+            mbcx.buffer_error(nice_error);
         } else {
-            self.fallback_error(tcx, span).buffer(&mut mbcx.errors_buffer);
+            mbcx.buffer_error(self.fallback_error(tcx, span));
         }
     }
 }
@@ -223,16 +202,16 @@ fn base_universe(&self) -> ty::UniverseIndex {
 
     fn nice_error(
         &self,
-        mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         cause: ObligationCause<'tcx>,
         placeholder_region: ty::Region<'tcx>,
         error_region: Option<ty::Region<'tcx>>,
     ) -> Option<DiagnosticBuilder<'tcx>> {
-        mbcx.infcx.tcx.infer_ctxt().enter_with_canonical(
+        tcx.infer_ctxt().enter_with_canonical(
             cause.span,
             &self.canonical_query,
             |ref infcx, key, _| {
-                let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
+                let mut fulfill_cx = <dyn TraitEngine<'_>>::new(tcx);
                 type_op_prove_predicate_with_cause(infcx, &mut *fulfill_cx, key, cause);
                 try_extract_error_from_fulfill_cx(
                     fulfill_cx,
@@ -266,16 +245,16 @@ fn base_universe(&self) -> ty::UniverseIndex {
 
     fn nice_error(
         &self,
-        mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         cause: ObligationCause<'tcx>,
         placeholder_region: ty::Region<'tcx>,
         error_region: Option<ty::Region<'tcx>>,
     ) -> Option<DiagnosticBuilder<'tcx>> {
-        mbcx.infcx.tcx.infer_ctxt().enter_with_canonical(
+        tcx.infer_ctxt().enter_with_canonical(
             cause.span,
             &self.canonical_query,
             |ref infcx, key, _| {
-                let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
+                let mut fulfill_cx = <dyn TraitEngine<'_>>::new(tcx);
 
                 let mut selcx = SelectionContext::new(infcx);
 
@@ -323,16 +302,16 @@ fn base_universe(&self) -> ty::UniverseIndex {
 
     fn nice_error(
         &self,
-        mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         cause: ObligationCause<'tcx>,
         placeholder_region: ty::Region<'tcx>,
         error_region: Option<ty::Region<'tcx>>,
     ) -> Option<DiagnosticBuilder<'tcx>> {
-        mbcx.infcx.tcx.infer_ctxt().enter_with_canonical(
+        tcx.infer_ctxt().enter_with_canonical(
             cause.span,
             &self.canonical_query,
             |ref infcx, key, _| {
-                let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
+                let mut fulfill_cx = <dyn TraitEngine<'_>>::new(tcx);
                 type_op_ascribe_user_type_with_span(infcx, &mut *fulfill_cx, key, Some(cause.span))
                     .ok()?;
                 try_extract_error_from_fulfill_cx(
@@ -346,39 +325,6 @@ fn nice_error(
     }
 }
 
-impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
-    fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
-        // FIXME: This error message isn't great, but it doesn't show up in the existing UI tests,
-        // and is only the fallback when the nice error fails. Consider improving this some more.
-        tcx.sess.struct_span_err(span, "higher-ranked lifetime error for opaque type!")
-    }
-
-    fn base_universe(&self) -> ty::UniverseIndex {
-        self.base_universe.unwrap()
-    }
-
-    fn nice_error(
-        &self,
-        mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
-        _cause: ObligationCause<'tcx>,
-        placeholder_region: ty::Region<'tcx>,
-        error_region: Option<ty::Region<'tcx>>,
-    ) -> Option<DiagnosticBuilder<'tcx>> {
-        try_extract_error_from_region_constraints(
-            mbcx.infcx,
-            placeholder_region,
-            error_region,
-            self.region_constraints.as_ref().unwrap(),
-            // We're using the original `InferCtxt` that we
-            // started MIR borrowchecking with, so the region
-            // constraints have already been taken. Use the data from
-            // our `mbcx` instead.
-            |vid| mbcx.regioncx.var_infos[vid].origin,
-            |vid| mbcx.regioncx.var_infos[vid].universe,
-        )
-    }
-}
-
 #[instrument(skip(fulfill_cx, infcx), level = "debug")]
 fn try_extract_error_from_fulfill_cx<'tcx>(
     mut fulfill_cx: Box<dyn TraitEngine<'tcx> + 'tcx>,
@@ -386,30 +332,15 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
     placeholder_region: ty::Region<'tcx>,
     error_region: Option<ty::Region<'tcx>>,
 ) -> Option<DiagnosticBuilder<'tcx>> {
+    let tcx = infcx.tcx;
+
     // We generally shouldn't have errors here because the query was
     // already run, but there's no point using `delay_span_bug`
     // when we're going to emit an error here anyway.
     let _errors = fulfill_cx.select_all_or_error(infcx);
-    let region_constraints = infcx.with_region_constraints(|r| r.clone());
-    try_extract_error_from_region_constraints(
-        infcx,
-        placeholder_region,
-        error_region,
-        &region_constraints,
-        |vid| infcx.region_var_origin(vid),
-        |vid| infcx.universe_of_region(infcx.tcx.mk_region(ty::ReVar(vid))),
-    )
-}
 
-fn try_extract_error_from_region_constraints<'tcx>(
-    infcx: &InferCtxt<'_, 'tcx>,
-    placeholder_region: ty::Region<'tcx>,
-    error_region: Option<ty::Region<'tcx>>,
-    region_constraints: &RegionConstraintData<'tcx>,
-    mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin,
-    mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex,
-) -> Option<DiagnosticBuilder<'tcx>> {
-    let (sub_region, cause) =
+    let (sub_region, cause) = infcx.with_region_constraints(|region_constraints| {
+        debug!("{:#?}", region_constraints);
         region_constraints.constraints.iter().find_map(|(constraint, cause)| {
             match *constraint {
                 Constraint::RegSubReg(sub, sup) if sup == placeholder_region && sup != sub => {
@@ -417,11 +348,12 @@ fn try_extract_error_from_region_constraints<'tcx>(
                 }
                 // FIXME: Should this check the universe of the var?
                 Constraint::VarSubReg(vid, sup) if sup == placeholder_region => {
-                    Some((infcx.tcx.mk_region(ty::ReVar(vid)), cause.clone()))
+                    Some((tcx.mk_region(ty::ReVar(vid)), cause.clone()))
                 }
                 _ => None,
             }
-        })?;
+        })
+    })?;
 
     debug!(?sub_region, "cause = {:#?}", cause);
     let nice_error = match (error_region, sub_region) {
@@ -429,7 +361,7 @@ fn try_extract_error_from_region_constraints<'tcx>(
             infcx,
             RegionResolutionError::SubSupConflict(
                 vid,
-                region_var_origin(vid),
+                infcx.region_var_origin(vid),
                 cause.clone(),
                 error_region,
                 cause.clone(),
@@ -446,8 +378,8 @@ fn try_extract_error_from_region_constraints<'tcx>(
             infcx,
             RegionResolutionError::UpperBoundUniverseConflict(
                 vid,
-                region_var_origin(vid),
-                universe_of_region(vid),
+                infcx.region_var_origin(vid),
+                infcx.universe_of_region(sub_region),
                 cause.clone(),
                 placeholder_region,
             ),