]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Add `TyCtxt::is_fn_trait`
[rust.git] / compiler / rustc_trait_selection / src / traits / error_reporting / mod.rs
index 59d017545c0324329e651fc31b575eb1f71456b8..e96b9b64e78749c0b16184d53682699986b1380d 100644 (file)
@@ -9,6 +9,7 @@
 };
 use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use crate::infer::InferCtxtExt as _;
 use crate::infer::{self, InferCtxt, TyCtxtInferExt};
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
 use crate::traits::query::normalize::AtExt as _;
@@ -28,7 +29,7 @@
 use rustc_hir::Item;
 use rustc_hir::Node;
 use rustc_infer::infer::error_reporting::TypeErrCtxt;
-use rustc_infer::infer::TypeTrace;
+use rustc_infer::infer::{InferOk, TypeTrace};
 use rustc_middle::traits::select::OverflowError;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::error::ExpectedFound;
@@ -356,7 +357,8 @@ fn type_implements_fn_trait(
                 ocx.register_obligation(obligation);
                 if ocx.select_all_or_error().is_empty() {
                     return Ok((
-                        ty::ClosureKind::from_def_id(self.tcx, trait_def_id)
+                        self.tcx
+                            .fn_trait_kind_from_def_id(trait_def_id)
                             .expect("expected to map DefId to ClosureKind"),
                         ty.rebind(self.resolve_vars_if_possible(var)),
                     ));
@@ -587,7 +589,7 @@ fn report_selection_error(
 
                 let bound_predicate = obligation.predicate.kind();
                 match bound_predicate.skip_binder() {
-                    ty::PredicateKind::Trait(trait_predicate) => {
+                    ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => {
                         let trait_predicate = bound_predicate.rebind(trait_predicate);
                         let mut trait_predicate = self.resolve_vars_if_possible(trait_predicate);
 
@@ -685,7 +687,7 @@ fn report_selection_error(
                                 }
                                 ObligationCauseCode::BindingObligation(def_id, _)
                                 | ObligationCauseCode::ItemObligation(def_id)
-                                    if ty::ClosureKind::from_def_id(tcx, *def_id).is_some() =>
+                                    if tcx.is_fn_trait(*def_id) =>
                                 {
                                     err.code(rustc_errors::error_code!(E0059));
                                     err.set_primary_message(format!(
@@ -845,8 +847,7 @@ fn report_selection_error(
                             );
                         }
 
-                        let is_fn_trait =
-                            ty::ClosureKind::from_def_id(tcx, trait_ref.def_id()).is_some();
+                        let is_fn_trait = tcx.is_fn_trait(trait_ref.def_id());
                         let is_target_feature_fn = if let ty::FnDef(def_id, _) =
                             *trait_ref.skip_binder().self_ty().kind()
                         {
@@ -876,7 +877,7 @@ fn report_selection_error(
                             // Note if the `FnMut` or `FnOnce` is less general than the trait we're trying
                             // to implement.
                             let selected_kind =
-                                ty::ClosureKind::from_def_id(self.tcx, trait_ref.def_id())
+                                self.tcx.fn_trait_kind_from_def_id(trait_ref.def_id())
                                     .expect("expected to map DefId to ClosureKind");
                             if !implemented_kind.extends(selected_kind) {
                                 err.note(
@@ -1051,9 +1052,9 @@ fn report_selection_error(
                         span_bug!(span, "coerce requirement gave wrong error: `{:?}`", predicate)
                     }
 
-                    ty::PredicateKind::RegionOutlives(..)
-                    | ty::PredicateKind::Projection(..)
-                    | ty::PredicateKind::TypeOutlives(..) => {
+                    ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
+                    | ty::PredicateKind::Clause(ty::Clause::Projection(..))
+                    | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) => {
                         let predicate = self.resolve_vars_if_possible(obligation.predicate);
                         struct_span_err!(
                             self.tcx.sess,
@@ -1473,9 +1474,10 @@ fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -
         // FIXME: It should be possible to deal with `ForAll` in a cleaner way.
         let bound_error = error.kind();
         let (cond, error) = match (cond.kind().skip_binder(), bound_error.skip_binder()) {
-            (ty::PredicateKind::Trait(..), ty::PredicateKind::Trait(error)) => {
-                (cond, bound_error.rebind(error))
-            }
+            (
+                ty::PredicateKind::Clause(ty::Clause::Trait(..)),
+                ty::PredicateKind::Clause(ty::Clause::Trait(error)),
+            ) => (cond, bound_error.rebind(error)),
             _ => {
                 // FIXME: make this work in other cases too.
                 return false;
@@ -1484,7 +1486,9 @@ fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -
 
         for obligation in super::elaborate_predicates(self.tcx, std::iter::once(cond)) {
             let bound_predicate = obligation.predicate.kind();
-            if let ty::PredicateKind::Trait(implication) = bound_predicate.skip_binder() {
+            if let ty::PredicateKind::Clause(ty::Clause::Trait(implication)) =
+                bound_predicate.skip_binder()
+            {
                 let error = error.to_poly_trait_ref();
                 let implication = bound_predicate.rebind(implication.trait_ref);
                 // FIXME: I'm just not taking associated types at all here.
@@ -1581,7 +1585,9 @@ fn report_projection_error(
             // this can fail if the problem was higher-ranked, in which
             // cause I have no idea for a good error message.
             let bound_predicate = predicate.kind();
-            if let ty::PredicateKind::Projection(data) = bound_predicate.skip_binder() {
+            if let ty::PredicateKind::Clause(ty::Clause::Projection(data)) =
+                bound_predicate.skip_binder()
+            {
                 let mut selcx = SelectionContext::new(self);
                 let data = self.replace_bound_vars_with_fresh_vars(
                     obligation.cause.span,
@@ -1629,7 +1635,7 @@ fn report_projection_error(
             let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}");
 
             let secondary_span = match predicate.kind().skip_binder() {
-                ty::PredicateKind::Projection(proj) => self
+                ty::PredicateKind::Clause(ty::Clause::Projection(proj)) => self
                     .tcx
                     .opt_associated_item(proj.projection_ty.item_def_id)
                     .and_then(|trait_assoc_item| {
@@ -2047,7 +2053,7 @@ fn maybe_report_ambiguity(
 
         let bound_predicate = predicate.kind();
         let mut err = match bound_predicate.skip_binder() {
-            ty::PredicateKind::Trait(data) => {
+            ty::PredicateKind::Clause(ty::Clause::Trait(data)) => {
                 let trait_ref = bound_predicate.rebind(data.trait_ref);
                 debug!(?trait_ref);
 
@@ -2111,11 +2117,8 @@ fn maybe_report_ambiguity(
                     )
                 };
 
-                let obligation = obligation.with(self.tcx, trait_ref.to_poly_trait_predicate());
-                let mut selcx = SelectionContext::with_query_mode(
-                    &self,
-                    crate::traits::TraitQueryMode::Standard,
-                );
+                let obligation = obligation.with(self.tcx, trait_ref);
+                let mut selcx = SelectionContext::new(&self);
                 match selcx.select_from_obligation(&obligation) {
                     Ok(None) => {
                         let impls = ambiguity::recompute_applicable_impls(self.infcx, &obligation);
@@ -2152,7 +2155,7 @@ fn maybe_report_ambiguity(
                     if generics.params.iter().any(|p| p.name != kw::SelfUpper)
                         && !snippet.ends_with('>')
                         && !generics.has_impl_trait()
-                        && !self.tcx.fn_trait_kind_from_lang_item(def_id).is_some()
+                        && !self.tcx.is_fn_trait(def_id)
                     {
                         // FIXME: To avoid spurious suggestions in functions where type arguments
                         // where already supplied, we check the snippet to make sure it doesn't
@@ -2327,7 +2330,7 @@ fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
                 assert!(a.is_ty_var() && b.is_ty_var());
                 self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282, true)
             }
-            ty::PredicateKind::Projection(data) => {
+            ty::PredicateKind::Clause(ty::Clause::Projection(data)) => {
                 if predicate.references_error() || self.tainted_by_errors().is_some() {
                     return;
                 }
@@ -2528,18 +2531,15 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
         }
 
         self.probe(|_| {
-            let mut selcx = SelectionContext::new(self);
-
             let cleaned_pred =
                 pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() });
 
-            let cleaned_pred = super::project::normalize(
-                &mut selcx,
-                param_env,
-                ObligationCause::dummy(),
-                cleaned_pred,
-            )
-            .value;
+            let InferOk { value: cleaned_pred, .. } =
+                self.infcx.partially_normalize_associated_types_in(
+                    ObligationCause::dummy(),
+                    param_env,
+                    cleaned_pred,
+                );
 
             let obligation =
                 Obligation::new(self.tcx, ObligationCause::dummy(), param_env, cleaned_pred);
@@ -2573,7 +2573,7 @@ fn suggest_unsized_bound_if_applicable(
         err: &mut Diagnostic,
         obligation: &PredicateObligation<'tcx>,
     ) {
-        let ty::PredicateKind::Trait(pred) = obligation.predicate.kind().skip_binder() else { return; };
+        let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = obligation.predicate.kind().skip_binder() else { return; };
         let (ObligationCauseCode::BindingObligation(item_def_id, span)
         | ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..))
             = *obligation.cause.code().peel_derives() else { return; };