diff options
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/mod.rs')
-rw-r--r-- | compiler/rustc_trait_selection/src/traits/mod.rs | 46 |
1 files changed, 21 insertions, 25 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index f036a311d..4e30108be 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -14,7 +14,6 @@ mod object_safety; pub mod outlives_bounds; mod project; pub mod query; -pub(crate) mod relationships; mod select; mod specialize; mod structural_match; @@ -27,12 +26,11 @@ use crate::infer::{InferCtxt, TyCtxtInferExt}; use crate::traits::error_reporting::TypeErrCtxtExt as _; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_errors::ErrorGuaranteed; -use rustc_hir as hir; -use rustc_hir::def_id::DefId; use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::visit::TypeVisitable; +use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeSuperVisitable}; use rustc_middle::ty::{InternalSubsts, SubstsRef}; +use rustc_span::def_id::{DefId, CRATE_DEF_ID}; use rustc_span::Span; use std::fmt::Debug; @@ -143,7 +141,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>( fn pred_known_to_hold_modulo_regions<'tcx>( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - pred: impl ToPredicate<'tcx> + TypeVisitable<'tcx>, + pred: impl ToPredicate<'tcx> + TypeVisitable<TyCtxt<'tcx>>, span: Span, ) -> bool { let has_non_region_infer = pred.has_non_region_infer(); @@ -152,29 +150,29 @@ fn pred_known_to_hold_modulo_regions<'tcx>( // We can use a dummy node-id here because we won't pay any mind // to region obligations that arise (there shouldn't really be any // anyhow). - cause: ObligationCause::misc(span, hir::CRATE_HIR_ID), + cause: ObligationCause::misc(span, CRATE_DEF_ID), recursion_depth: 0, predicate: pred.to_predicate(infcx.tcx), }; - let result = infcx.predicate_must_hold_modulo_regions(&obligation); + let result = infcx.evaluate_obligation_no_overflow(&obligation); debug!(?result); - if result && has_non_region_infer { + if result.must_apply_modulo_regions() && !has_non_region_infer { + true + } else if result.may_apply() { // Because of inference "guessing", selection can sometimes claim // to succeed while the success requires a guess. To ensure // this function's result remains infallible, we must confirm // that guess. While imperfect, I believe this is sound. // FIXME(@lcnr): this function doesn't seem right. + // // The handling of regions in this area of the code is terrible, // see issue #29149. We should be able to improve on this with // NLL. let errors = fully_solve_obligation(infcx, obligation); - // Note: we only assume something is `Copy` if we can - // *definitively* show that it implements `Copy`. Otherwise, - // assume it is move; linear is always ok. match &errors[..] { [] => true, errors => { @@ -183,7 +181,7 @@ fn pred_known_to_hold_modulo_regions<'tcx>( } } } else { - result + false } } @@ -285,7 +283,7 @@ pub fn normalize_param_env_or_error<'tcx>( debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates); let elaborated_env = ty::ParamEnv::new( - tcx.intern_predicates(&predicates), + tcx.mk_predicates(&predicates), unnormalized_env.reveal(), unnormalized_env.constness(), ); @@ -337,10 +335,9 @@ pub fn normalize_param_env_or_error<'tcx>( // Not sure whether it is better to include the unnormalized TypeOutlives predicates // here. I believe they should not matter, because we are ignoring TypeOutlives param-env // predicates here anyway. Keeping them here anyway because it seems safer. - let outlives_env: Vec<_> = - non_outlives_predicates.iter().chain(&outlives_predicates).cloned().collect(); + let outlives_env = non_outlives_predicates.iter().chain(&outlives_predicates).cloned(); let outlives_env = ty::ParamEnv::new( - tcx.intern_predicates(&outlives_env), + tcx.mk_predicates_from_iter(outlives_env), unnormalized_env.reveal(), unnormalized_env.constness(), ); @@ -360,7 +357,7 @@ pub fn normalize_param_env_or_error<'tcx>( predicates.extend(outlives_predicates); debug!("normalize_param_env_or_error: final predicates={:?}", predicates); ty::ParamEnv::new( - tcx.intern_predicates(&predicates), + tcx.mk_predicates(&predicates), unnormalized_env.reveal(), unnormalized_env.constness(), ) @@ -375,7 +372,7 @@ pub fn fully_normalize<'tcx, T>( value: T, ) -> Result<T, Vec<FulfillmentError<'tcx>>> where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { let ocx = ObligationCtxt::new(infcx); debug!(?value); @@ -485,7 +482,7 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI generics: &'tcx ty::Generics, trait_item_def_id: DefId, } - impl<'tcx> ty::TypeVisitor<'tcx> for ReferencesOnlyParentGenerics<'tcx> { + impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for ReferencesOnlyParentGenerics<'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { // If this is a parameter from the trait item's own generics, then bail @@ -527,16 +524,14 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI let mut visitor = ReferencesOnlyParentGenerics { tcx, generics, trait_item_def_id }; let predicates_for_trait = predicates.predicates.iter().filter_map(|(pred, span)| { - if pred.visit_with(&mut visitor).is_continue() { - Some(Obligation::new( + pred.visit_with(&mut visitor).is_continue().then(|| { + Obligation::new( tcx, ObligationCause::dummy_with_span(*span), param_env, ty::EarlyBinder(*pred).subst(tcx, impl_trait_ref.substs), - )) - } else { - None - } + ) + }) }); let infcx = tcx.infer_ctxt().ignoring_regions().build(); @@ -558,6 +553,7 @@ pub fn provide(providers: &mut ty::query::Providers) { specialization_graph_of: specialize::specialization_graph_provider, specializes: specialize::specializes, subst_and_check_impossible_predicates, + check_tys_might_be_eq: misc::check_tys_might_be_eq, is_impossible_method, ..*providers }; |