about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJack Huey <31162821+jackh726@users.noreply.github.com>2021-12-13 01:10:39 -0500
committerJack Huey <31162821+jackh726@users.noreply.github.com>2021-12-13 01:10:39 -0500
commit7cbd0dcf9372814cacc43d1860fce8bd36c44489 (patch)
tree7e3cf32c635077c1b12518b8691a81a23f658121
parent8a28c172a128dee00debcf828e2243e94d56fb5f (diff)
I wrote these functions, I should use them dang it
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs152
1 files changed, 60 insertions, 92 deletions
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index 6fba3d3ad08..3576764596c 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -14,9 +14,8 @@ use rustc_hir::lang_items::LangItem;
 use rustc_hir::ItemKind;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::outlives::obligations::TypeOutlives;
+use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::infer::{self, RegionckMode, SubregionOrigin};
-use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
-use rustc_infer::traits::TraitEngine;
 use rustc_middle::hir::map as hir_map;
 use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
 use rustc_middle::ty::trait_def::TraitSpecializationKind;
@@ -27,9 +26,7 @@ use rustc_session::parse::feature_err;
 use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
-use rustc_trait_selection::traits::{
-    self, ObligationCause, ObligationCauseCode, TraitEngineExt, WellFormedLoc,
-};
+use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, WellFormedLoc};
 
 use std::convert::TryInto;
 use std::iter;
@@ -435,99 +432,70 @@ fn check_gat_where_clauses(
     if !clauses.is_empty() {
         let param_env = tcx.param_env(trait_item.def_id);
 
-        // This shouldn't really matter, but we need it
-        let cause = traits::ObligationCause::new(
-            trait_item.span,
-            trait_item.hir_id(),
-            ObligationCauseCode::MiscObligation,
-        );
-        // Create an `InferCtxt` to try to prove the clauses we require
-        tcx.infer_ctxt().enter(|infcx| {
-            let mut fulfillment_cx = <dyn TraitEngine<'_>>::new(tcx);
-
-            // Register all the clauses as obligations
-            clauses
-                .clone()
-                .into_iter()
-                .map(|predicate| {
-                    traits::Obligation::new(
-                        cause.clone(),
+        let mut clauses: Vec<_> = clauses
+            .into_iter()
+            .filter(|clause| match clause.kind().skip_binder() {
+                ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => {
+                    !region_known_to_outlive(
+                        tcx,
+                        trait_item.hir_id(),
                         param_env,
-                        predicate,
+                        &FxHashSet::default(),
+                        a,
+                        b,
                     )
-                })
-                .for_each(|obligation| {
-                    fulfillment_cx.register_predicate_obligation(&infcx, obligation)
-                });
-
-            // Convert these obligations into constraints by selecting
-            let errors = fulfillment_cx.select_all_or_error(&infcx);
-            if !errors.is_empty() {
-                bug!("should have only registered region obligations, which get registerd as constraints");
-            }
+                }
+                ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => {
+                    !ty_known_to_outlive(
+                        tcx,
+                        trait_item.hir_id(),
+                        param_env,
+                        &FxHashSet::default(),
+                        a,
+                        b,
+                    )
+                }
+                _ => bug!("Unexpected PredicateKind"),
+            })
+            .map(|clause| format!("{}", clause))
+            .collect();
 
-            // FIXME(jackh726): some of this code is shared with `regionctxt`, but in a different
-            // flow; we could probably better extract the shared logic
-
-            // Process the region obligations
-            let body_id_map = infcx
-                .inner
-                .borrow()
-                .region_obligations()
-                .iter()
-                .map(|&(id, _)| (id, vec![]))
-                .collect();
-
-            infcx.process_registered_region_obligations(&body_id_map, None, param_env);
-
-            // Resolve the region constraints to find any constraints that we're provable
-            let outlives_env = OutlivesEnvironment::new(param_env);
-            let errors = infcx.resolve_regions(trait_item.def_id.to_def_id(), &outlives_env, RegionckMode::default());
-
-            // Emit an error if there are non-provable constriants
-            if !errors.is_empty() {
-                let mut clauses: Vec<_> = errors.into_iter().map(|error| match error {
-                    RegionResolutionError::ConcreteFailure(_, sup, sub) => format!("{}: {}", sub, sup),
-                    RegionResolutionError::GenericBoundFailure(_, sub, sup) => format!("{}: {}", sub, sup),
-                    _ => bug!("Unexpected region resolution error when resolving outlives lint"),
-                }).collect();
-                clauses.sort();
-
-                let plural = if clauses.len() > 1 { "s" } else { "" };
-                let mut err = tcx.sess.struct_span_err(
-                    trait_item.span,
-                    &format!("missing required bound{} on `{}`", plural, trait_item.ident),
-                );
+        // We sort so that order is predictable
+        clauses.sort();
 
-                let suggestion = format!(
-                    "{} {}",
-                    if !trait_item.generics.where_clause.predicates.is_empty() {
-                        ","
-                    } else {
-                        " where"
-                    },
-                    clauses.join(", "),
-                );
-                err.span_suggestion(
-                    trait_item.generics.where_clause.tail_span_for_suggestion(),
-                    &format!("add the required where clause{}", plural),
-                    suggestion,
-                    Applicability::MachineApplicable,
-                );
+        if !clauses.is_empty() {
+            let plural = if clauses.len() > 1 { "s" } else { "" };
+            let mut err = tcx.sess.struct_span_err(
+                trait_item.span,
+                &format!("missing required bound{} on `{}`", plural, trait_item.ident),
+            );
 
-                let bound = if clauses.len() > 1 { "these bounds are" } else { "this bound is" };
-                err.note(
-                    &format!("{} required to ensure that impls have maximum flexibility", bound)
-                );
-                err.note(
-                    "see issue #87479 \
-                     <https://github.com/rust-lang/rust/issues/87479> \
-                     for more information",
-                );
+            let suggestion = format!(
+                "{} {}",
+                if !trait_item.generics.where_clause.predicates.is_empty() {
+                    ","
+                } else {
+                    " where"
+                },
+                clauses.join(", "),
+            );
+            err.span_suggestion(
+                trait_item.generics.where_clause.tail_span_for_suggestion(),
+                &format!("add the required where clause{}", plural),
+                suggestion,
+                Applicability::MachineApplicable,
+            );
 
-                err.emit()
-            }
-        });
+            let bound = if clauses.len() > 1 { "these bounds are" } else { "this bound is" };
+            err.note(&format!("{} required to ensure that impls have maximum flexibility", bound));
+            err.note(
+                "see issue #87479 \
+                 <https://github.com/rust-lang/rust/issues/87479> \
+                 for more information",
+            );
+
+            err.emit()
+        }
     }
 }